Para simplificar a interface, é melhor simplesmente não ter o getBalance()
método? Passar 0
para o charge(float c);
dará o mesmo resultado:
public class Client {
private float bal;
float getBalance() { return bal; }
float charge(float c) {
bal -= c;
return bal;
}
}
Talvez faça uma anotação javadoc
? Ou deixe o usuário da classe descobrir como obter o equilíbrio?
interfaces
cqrs
david
fonte
fonte
Respostas:
Você parece sugerir que a complexidade de uma interface é medida pelo número de elementos que ela possui (métodos, neste caso). Muitos argumentariam que ter que lembrar que o
charge
método pode ser usado para retornar o equilíbrio de aClient
adiciona muito mais complexidade do que ter o elemento extra dogetBalance
método. Tornar as coisas mais explícitas é muito mais simples, especialmente ao ponto em que não deixa ambiguidade, independentemente do maior número de elementos na interface.Além disso, a chamada
charge(0)
viola o princípio de menos espanto , também conhecido como métrica WTFs por minuto (do Código Limpo, imagem abaixo), dificultando a entrada de novos membros da equipe (ou atuais, após algum tempo longe do código) até eles entendem que a chamada é realmente usada para obter o equilíbrio. Pense em como outros leitores reagiriam:Além disso, a assinatura do
charge
método contraria as diretrizes de fazer uma e apenas uma coisa e separar a consulta de comando , porque faz com que o objeto altere seu estado e também retorna um novo valor.Em suma, acredito que a interface mais simples nesse caso seria:
fonte
getBalance()
retorna algum valor e não modifica nada. Por outro lado,charge(0)
parece que provavelmente modifica algo ... talvez ele envie um evento PropertyChanged? E o que está retornando, o valor anterior ou o novo valor? Agora você deve procurar nos documentos e desperdiçar recursos intelectuais, o que poderia ter sido evitado usando um método mais claro.charge(0)
como a maneira de obter o equilíbrio, porque agora não tem efeito, ajuda você a esse detalhe da implementação; Posso facilmente imaginar um requisito futuro em que o rastreamento do número de cobranças se torna relevante; nesse momento, ter sua base de códigos repleta de cobranças que não são realmente cobranças se torna um problema. Você deve fornecer elementos de interface que significam as coisas que seus clientes precisam fazer, não aqueles que simplesmente fazem o que seus clientes precisam fazer.charge()
método, se esse método for atômico em um sistema simultâneo, pode ser apropriado retornar o valor novo ou antigo.IMO, substituindo
getBalance()
comcharge(0)
toda a sua aplicação não é uma simplificação. Sim, são menos linhas, mas ofusca o significado docharge()
método, o que pode causar dores de cabeça na linha quando você ou outra pessoa precisa revisitar esse código.Embora eles possam dar o mesmo resultado, obter o saldo de uma conta não é o mesmo que cobrar zero, portanto, provavelmente seria melhor separar suas preocupações. Por exemplo, se você precisar modificar o
charge()
log sempre que houver uma transação na conta, agora terá um problema e precisará separar a funcionalidade de qualquer maneira.fonte
É importante lembrar que seu código deve ser auto-documentado. Quando ligo
charge(x)
, esperox
ser cobrado. As informações sobre o equilíbrio são secundárias. Além do mais, talvez eu não saiba comocharge()
é implementado quando o chamo e definitivamente não saberei como ele será implementado amanhã. Por exemplo, considere esta atualização futura em potencial paracharge()
:De repente, usar
charge()
para obter o equilíbrio não parece tão bom.fonte
charge
é muito mais pesado.Usar
charge(0);
para obter o saldo é uma péssima ideia: um dia, alguém pode adicionar algum código para registrar as cobranças feitas sem perceber o outro uso da função e, toda vez que alguém obtiver o saldo, ela será registrada como cobrança. (Existem maneiras de contornar isso, como uma declaração condicional que diz algo como:mas isso depende do programador saber implementá-los, o que ele não fará se não for imediatamente óbvio que eles são necessários.
Resumindo: não confie nos usuários ou nos sucessores de programadores que percebem que
charge(0);
é a maneira correta de obter o equilíbrio, porque, a menos que exista documentação que garantam que eles não perderão, francamente, essa será a maneira mais assustadora de obter o equilíbrio. possível.fonte
Sei que há muitas respostas, mas outro motivo
charge(0)
é que um simples erro de digitaçãocharge(9)
fará com que o saldo de seu cliente diminua toda vez que você desejar obter o equilíbrio. Se você tiver um bom teste de unidade, poderá mitigar esse risco, mas, se não for diligente em todas as ligações,charge
poderá ter esse problema.fonte
Eu gostaria de mencionar um caso específico em que faria sentido ter menos métodos, mais polivalentes: se houver muito polimorfismo, ou seja, muitas implementações dessa interface ; especialmente se essas implementações estiverem em código desenvolvido separadamente e não puderem ser atualizados em sincronia (a interface é definida por uma biblioteca).
Nesse caso, simplificar o trabalho de escrever cada implementação é muito mais valioso do que a clareza de uso, porque a primeira evita erros de violação de contrato (os dois métodos são inconsistentes entre si), enquanto a última apenas prejudica a legibilidade, o que pode ser recuperado por uma função auxiliar ou método de superclasse que defina
getBalance
em termos decharge
.(Esse é um padrão de design, para o qual não recordo um nome específico: definição de uma interface complexa e amigável para quem chama em termos de uma interface mínima para o implementador. No Classic Mac OS, a interface mínima para operações de desenho era chamada de "gargalo" mas esse parece não ser um termo popular.)
Se esse não for o caso (existem poucas implementações ou exatamente uma)
charge()
, faz sentido separar os métodos para maior clareza e permitir a simples adição de comportamentos relevantes a cobranças diferentes de zero .fonte
realloc
, às vezes, em alguns sistemas.