Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

Instanciamento no construtor

Vimos que no método construtor das entidades, já passamos o valor dos atributos.

Se eu preferir não usar o método construtor, mas preferir instanciar pelos métodos da classe, é errado?

Eu pergunto isso porque nem sempre uso todos os métodos quando a entidade é instanciada.

4 respostas

Fala, Flavio.

Você nunca deve permitir que um objeto esteja em um estado inválido.

Então, se um atributo é obrigatório para que sua entidade seja válida, você deve sim recebê-lo no construtor.

Ex.: Existe aluno sem nome? Não, né!? Então o nome precisa estar no construtor para que eu não consiga criar um aluno sem nome, entende?

Abraços e bons estudos.

Vou dar um exemplo.

Considerando as entidades Pagamento e Parcela. Considere que estamos falando de pagamentos parcelados.

A entidade Pagamento tem vários atributos. Mas para ser válida temos apenas 3:

  • Descrição
  • Valor do pagamento
  • Vencimento
class Pagamento
{
    private $descricao;
    private $valorPagamento;
    private $vencimento;
    private $outro_atributo1
    private $outro_atributo2

    function __construct($descricao, $valorPagamento, $vencimento)
    {
        $this->descricao = $descricao;
        $this->valorPagamento = $valorPagamento
        $this->vencimento = $vencimento;
    }

    // outros métodos...

}

Até aqui blz. Entendido.

Só que vamos imaginar uma suposta consulta de uma lista de pagamentos. Nela não importa exibir o valor do pagamento nem o vencimento dele. Importa ter o valor da parcela e o vencimento dela, pois, como falamos, são pagamentos parcelados.

Para isso tenho o método pagamentosParcelados() no repositório. Estou implementando aquele processo de hidratação.

// este método está no repositório Pagamento
public function pagamentosParcelados()
{
    $sql = "MINHA SQL" // nesta sql só interessa a descrição do pagamento. O resto dos dados referem-se às parcelas.
    $stmt = $this->conexao->query($sql)
    $pagtosParceladosDados = $stmt->fetchAll();



    // hidratação
    $listaPagtosParcelados = [];
    foreach ($pagtosParceladosDados as $pagto) {
        $listaPagtosParcelados = new Pagamento (...) // ---> aqui está a dúvida.
    }

    // restante do código...
}

Aqui está a dúvida: Se a entidade Pagamento requer alguns atributos no construtor que, neste caso, não serão usados, mesmo assim preciso definí-los.

Fiquei confuso pois:

  • Se criando um pagamento, estes atributos são obrigatórios. Aí tudo bem. Preciso destes métodos, senão o objeto fica em um estado inválido.
  • Mas se estou fazendo esta consulta aí, só vou usar o atributo da descrição do pagamento. Os outros dois não serão imporantes para a consulta.

Quer dizer então que, neste caso, sou obrigado a instanciar o objeto com dois atributos que não vou utilizar na minha consulta, só porque preciso que eles estejam no construtor?

solução!

Se a entidade Pagamento requer alguns atributos no construtor que, neste caso, não serão usados, mesmo assim preciso definí-los.

Se existe a possibilidade de haver um pagamento sem algum atributo, esse atributo não é obrigatório, logo, não precisa estar no construtor...

Quanto ao seu modelo, ele não parece fazer sentido.

Ex.: O Pagamento devia ter uma lista de Parcelas. Não era ele pra ter um atributo $valorPagamento. Era pra ele ter um método valorTotal() que retorna a soma do valor de cada parcela, entende?

Seu problema não tá no entendimento da entidade, e sim na modelagem das classes, pelo que eu entendi...

Entendido. Perfeito.

Quanto à modelagem, realmente ela precisa de refatoração. Não foi um exemplo muito feliz :)

Obrigado!