[quote=RafaelVS]
Então, imagine que Conta tenha duas operações: creditar e debitar. Ambas atualizam o atributo saldo, uma incrementando uma valor e outra decrementando. Além disso, a operação debitar precisa validar se a conta tem saldo suficiente.
A) Dependendo do projeto, podemos na classe Conta criar simplesmente um método setSaldo(double valor) que atualizará o saldo com o valor informado, sem fazer nenhuma validação.
Na classe que trata das regras de negócio (aqui chamada de CadastroConta) deverá ter os métodos creditar() e debitar(). O método creditar() simplesmete somaria o valor e chamaria o setSaldo(novoValor) da conta. O método debitar() faz a validação, verificando se a conta tem saldo suficiente para debitar o valor informado e chama o método setSaldo(novoValor), onde o novoValor já é o valor final, após diminuir o saldo.
B) Outra opção, seria na própria classe Conta ter os métodos creditar() e debitar(), que funcionam como um “setSaldo” só que já contém implementação de regras de validação, se necessário. Aqui simplificaríamos os métodos na classe CadastroConta, que não precisariam fazer validação e simplesmente delegar a operação para a classe básica, que fará a validação.
Uma vantagem em tomar a decisão A é que vc está aumentando a possibilidade de reuso da classe Conta… já que ela não tem nenhum tipo de validação… por exemplo, se vc colocar o sistema em um outro banco onde a validação para a operação debitar é verificar se tem saldo com algum limite especial, a sua classe Conta não seria afetada… vc só precisaria mudar no método da classe CadastroConta. Uma desvantagem é que vc poderia, sem querer, através de algum método chamar diretamente o setSaldo(valor) podendo passar um valor sem fazer validação (mas se vc tomar a decisão de poder reusar a classe Conta, vc terá que tomar esse cuidado de não utilizar o método de maneira indevida)
Uma vantagem em tomar a decisão B é que ficará mais seguro… a partir de qualquer lugar vc pode chamar o método debitar() passando um valor inválido que o método irá validar corretamente e só atualizará os dados se tal operação for válida. Uma desvantagem é que se vc precisar reutilizar essa classe em um banco que usa uma política diferente para validação (como a que citei acima) vc precisaria escrever uma nova classe Conta para aquele banco.
A mesma idéia serve para o método creditar()… se ele é definido no CadastroConta e eu precisar reusar a classe Conta em um sistema que tem uma política diferente para creditar (por exemplo, se o saldo a ser creditado for maior do que X, será dado algum bônus para o cliente da conta) eu poderei fazer isso. Pois a classe Conta tem apenas um método setSaldo() sem validação e eu posso usa-lo tanto para creditar quanto para debitar (independente da regra envolvida)
Por isso falei que isso é uma questão de decisão de projeto… não tem a forma certa ou errada, vc é quem decide, nesse caso, se vai querer integridade dos dados ou se vai querer maior possibilidade de reuso.[/quote]
Não é por nada não. Mas o argumento que você usou pra opção A é pouquíssimo convincente. Você acredita que se deva fazer a separação entre uma classe com métodos (CadastroConta) e uma classe com propriedades (Conta), pois a primeira pode variar entre bancos, e a segunda seria estático. Ora, quem garante que as propriedades de Conta também não mudam entre bancos? Isso não faz sentido!
Talvez um jeito de garantir reúso seja a utilização de design patterns como o Template Method, do jeito que você falou, o reúso não acontece.