Para você ser marceneiro você tem que saber o que é madeira. Para vc trabalhar com OO, vc tem que saber SoC.
Senão vc não está fazendo OO. Este é o ponto.
Sim, muita gente tem duvidas quanto a SoC. Mas esse é o tipo de coisa difícil de explicar no forum. Vamos então com algumas coisas básicas.
O que é o básico do SoC ? Cada classe deve ter o minimo de responsabilidade possivel, mas não menos.
Se eu cozinho sou cozinheiro, se vendo, vendedor, se como, comilão
se choro, chorão … se valido ?
Validador!!!
Validações são feitas por validadores! Não por serviços. Não por entidades. Não por DAO, não por nada que não tenha a única e exclusiva responsabilidade de validar.
isSenhaValida é um caso para um validador de senha. “Senha” , pasmem-se, é uma entidade. Ela só não é um agregado.
Então aqui já temos : Senha e Validador
Mudar se senha… humm… mudar de senha é um assunto delicado. O que acontece se algum passo der errado ?
hummm… isso soa a transação… é! transação. E transação é coisa para serviços.
Usuários têm senhas, não são senhas. Senhas não são atributos do usuário, são associadas a usuários. ( um atributo é associado, mas algo associado, não é necessariamente um atributo)
Um usuário pode ter mais do que uma senha conforme o que a senha protege. É para isso que existe o single sign on (uma senha to rule them all => existe mais que uma).
Usuário.temPermissão(paraLevarTodoOdinheiroDoBancoParaCasa) ? O que vc acha que ele irá responder ?
Verificação de permissões é feita por um agente de segurança ( um Guardian), não pelo o usuário. O modelo é o seguinte: o sistema tem que ser protegido. Para isso existem agentes de segurança que autenticam e autorizam (ou não) o usuário. Vários agentes, várias permissões, um usuário.
Em um banco, A compra ações de B. Quem faz a transação ? o Broker. Quando existe um terceiro cara isso significa : serviço. (Serviço de Broker , ou Broking. Já ouviu falar?)
Qual é a responsabilidade de um entidade ? Ter identidade. São simples quanto isso. Para isso ela tem que ser criada. Aqui que complica. Manter o estado do objeto é simples (get/set) mas e manter o estado do sistema ? posso dar set em qualquer objeto a qualquer hora ? Não. Isso é delicado. É coisa para alguem responsável. Mais responsável que a entidade : o serviço.
Quem pinta é pintor, quem constrói é … ?
Construtor.
O padrão Builder é para criar objetos ( entidade é um caso particular de objeto) com estado consistente quando usar set não é atómico o suficiente ( ou seja, vc precisaria setar duas ou mais coisas simultaneamente e isso , simplesmente, é impossível com set)
Métodos “set” são Modificadores. Isso significa que estão mudando algo. Isso significa que eles não criam nada, apenas alteram. Para criar é preciso usar construtores ou outros objetos como Builder.
(é por isso que injeção via método set é furada na certa. só viável em caso em que a dependência é opcional.)
produto.alteraQuantidadeEstoque ( 20) … hummm… e quando o produto está em rota dentro de um caminhão. O que esse método faz ? manda um sms para o armazém ?
Produto tem um estoque ? Não. Estoque tem produtos.
Estoque.alteraQuantidade(Produto, 20) seria melhor. Melhor ainda :
Quantidade<Produto> quantidadeTransferida1 = estoqueA.remove(produto, 20);
estoqueB.adiciona(quantidadeTransferida1);
Transferencia transferencia1 = Transferencia.nova(estoqueA, estoqueB, quantidadeTransferida1 , relogio.agora());
Logger.log(transferencia1);
//diferente de:
Quantidade<Produto> quantidadeTransferida2 = estoqueB.remove(produto, 20);
estoqueA.adiciona(quantidadeTransferida2);
Transferencia transferencia2 = Transferencia.nova(estoqueB, estoqueA, quantidadeTransferida2 , relogio.agora());
Logger.log(transferencia2);
ups…enganei-me
Transferencia estorno = transferencia2.reverse(); // transferencias sabem como seria a sua "anti-transferencia. isto é um método que não altera dados, cria outra coisa, mas não precisa ser transacional.
Logger.log(estorno);
Quantidade<Produto> quantidadeTransferida3 = estoqueB.remove(produto, 40);
estoqueA.adiciona(quantidadeTransferida3);
Transferencia correto = Transferencia.nova(estoqueB, estoqueA, quantidadeTransferida3 , relogio.agora());
Logger.log(correto );
O assunto é vasto e complexo. Isto é só uma base.
Ah! e Validação é feita por Validadores. Objetos são responsáveis pela sua Consistência.
Validação != Consistência.