1
resposta

[Projeto] Faça como eu fiz: sistema de pagamentos

Resolução:
IPagamento.cs

namespace PraticandoC_05.SistemaDePagamentos08
{
    internal interface IPagamento
    {
        void ProcessarPagamento();
    }
}

Pessoa.cs

namespace PraticandoC_05.SistemaDePagamentos08
{
    internal abstract class Pessoa
    {
        public string? Nome { get; protected set; }
        public string? Email { get; protected set; }

    }
}

PagamentoBoleto.cs

namespace PraticandoC_05.SistemaDePagamentos08
{
    internal class PagamentoBoleto : Pessoa, IPagamento
    {
        public PagamentoBoleto(string? nome, string? email)
        {
            Nome = nome;
            Email = email;
        }
        public void ProcessarPagamento()
        {
            Console.WriteLine($"Processando pagamento via boleto para {Nome} - {Email}...");
            Thread.Sleep(3000);
            Console.WriteLine("Pagamento via boleto efetuado com Êxito!");
        }
    }
}

PagamentoCredito.cs

namespace PraticandoC_05.SistemaDePagamentos08
{
    internal class PagamentoCredito : Pessoa, IPagamento
    {
        public PagamentoCredito(string? nome, string? email)
        {
            Nome = nome;
            Email = email;
        }
        public void ProcessarPagamento()
        {
            Console.WriteLine($"Processando pagamento com cartão de crédito para {Nome} - {Email}...");
            Thread.Sleep(3000);
            Console.WriteLine("Pagamento com crédito efetuado com Êxito!");
        }
    }
}

Program.cs

PagamentoCredito cliente11 = new PagamentoCredito("André", "andre@email.com");
PagamentoBoleto cliente22 = new PagamentoBoleto("Juliana", "juliana@email.com");

cliente11.ProcessarPagamento();
Console.WriteLine("\nPressione qualquer tecla para continuar.\n");
Console.ReadKey();
cliente22.ProcessarPagamento();
1 resposta

Olá, Christopher. Como vai?

Parabéns por concluir mais um desafio do curso! A sua implementação do sistema de pagamentos utiliza recursos muito importantes do C#, como interfaces (IPagamento), classes abstratas (Pessoa) e simulação de concorrência/atraso com o método Thread.Sleep().

Apesar de o código compilar e funcionar visualmente no console, a estrutura atual apresenta um erro conceitual grave de modelagem orientada a objetos (OO). Você utilizou a Herança em uma relação onde deveria ter aplicado a Composição.

Vamos entender a fundo o que está acontecendo e como corrigir o design do seu software.

O Erro Conceitual da Herança

No seu código, as classes foram declaradas assim:
internal class PagamentoBoleto : Pessoa, IPagamento

A regra de ouro da herança dita que a relação entre a classe filha e a classe mãe deve ser do tipo "É um". Se formos traduzir a sua linha de código para o mundo real, ela está dizendo que "Um Pagamento via Boleto é uma Pessoa".

Fazer uma forma de pagamento herdar de um ser humano quebra a lógica de herança. O correto é entender que o Pagamento é uma ação ou um documento que tem uma Pessoa associada a ele como cliente.

Como Corrigir Utilizando Composição

Para ajustar o design do seu sistema seguindo os padrões de arquitetura de mercado, o ideal é desvincular o pagamento da herança de Pessoa e transformar a pessoa em uma propriedade (um componente) interna do pagamento.

Veja abaixo como reestruturar o projeto de forma limpa e profissional:

Pessoa.cs (Mantemos como uma classe comum concreta para representar o cliente)

namespace PraticandoC_05.SistemaDePagamentos08
{
    internal class Pessoa
    {
        public string? Nome { get; set; }
        public string? Email { get; set; }

        public Pessoa(string? nome, string? email)
        {
            Nome = nome;
            Email = email;
        }
    }
}

PagamentoBoleto.cs (Aplicando a Composição com Pessoa)

namespace PraticandoC_05.SistemaDePagamentos08
{
    internal class PagamentoBoleto : IPagamento
    {
        // O pagamento NÃO É uma pessoa, ele TEM uma pessoa (Composição)
        public Pessoa Cliente { get; }

        public PagamentoBoleto(Pessoa cliente)
        {
            Cliente = cliente;
        }

        public void ProcessarPagamento()
        {
            Console.WriteLine($"Processando pagamento via boleto para {Cliente.Nome} - {Cliente.Email}...");
            Thread.Sleep(3000);
            Console.WriteLine("Pagamento via boleto efetuado com êxito!");
        }
    }
}

PagamentoCredito.cs (Aplicando a Composição com Pessoa)

namespace PraticandoC_05.SistemaDePagamentos08
{
    internal class PagamentoCredito : IPagamento
    {
        public Pessoa Cliente { get; }

        public PagamentoCredito(Pessoa cliente)
        {
            Cliente = cliente;
        }

        public void ProcessarPagamento()
        {
            Console.WriteLine($"Processando pagamento com cartão de crédito para {Cliente.Nome} - {Cliente.Email}...");
            Thread.Sleep(3000);
            Console.WriteLine("Pagamento com crédito efetuado com êxito!");
        }
    }
}

O Novo Fluxo no Program.cs

Com essa alteração, a criação dos objetos fica muito mais organizada e realista. Primeiro criamos os clientes e, depois, associamos esses clientes aos seus respectivos pagamentos:

using PraticandoC_05.SistemaDePagamentos08;

// 1. Criamos as instâncias das pessoas
Pessoa andre = new Pessoa("André", "andre@email.com");
Pessoa juliana = new Pessoa("Juliana", "juliana@email.com");

// 2. Criamos os pagamentos injetando o cliente correspondente
IPagamento pagamento1 = new PagamentoCredito(andre);
IPagamento pagamento2 = new PagamentoBoleto(juliana);

// 3. Executamos o processamento polimórfico
pagamento1.ProcessarPagamento();
Console.WriteLine("\nPressione qualquer tecla para continuar.\n");
Console.ReadKey();
pagamento2.ProcessarPagamento();

Repare que no Program.cs reestruturado eu declarei as variáveis utilizando o tipo da interface (IPagamento pagamento1 = ...). Isso é uma excelente prática chamada Programar voltado para Interfaces, permitindo que o seu sistema trate qualquer forma de pagamento de maneira genérica e padronizada.

Fazer essa mudança vai elevar o nível do seu código e consolidar o aprendizado do capítulo sobre quando usar herança ou composição!

Espero que possa ter lhe ajudado!