Se eu tentar criar um novo método para manipular B de maneira diferente, ele será chamado para duplicação de código.
Nem toda duplicação de código é criada da mesma forma.
Digamos que você tenha um método que use dois parâmetros e os adicione juntos, chamados total()
. Digamos que você tenha outro chamado add()
. Suas implementações parecem completamente idênticas. Eles devem ser mesclados em um método? NÃO!!!
O princípio de não repetir a si mesmo ou DRY não se refere à repetição de código. Trata-se de espalhar uma decisão, uma idéia, para que, se você mudar de idéia, tenha que reescrever todos os lugares em que espalhar essa idéia. Blegh. Isso é terrível. Não faça isso. Em vez disso, use DRY para ajudá-lo a tomar decisões em um só lugar .
O princípio DRY (não se repita) afirma:
Todo conhecimento deve ter uma representação única, inequívoca e autoritativa dentro de um sistema.
wiki.c2.com - Não se repita
Porém, o DRY pode ser corrompido com o hábito de digitalizar código, procurando uma implementação semelhante que parece ser uma cópia e colagem de outro lugar. Esta é a forma de morte cerebral do DRY. Inferno, você poderia fazer isso com uma ferramenta de análise estática. Isso não ajuda porque ignora o ponto de DRY, que é manter o código flexível.
Se meus requisitos totais mudarem, talvez seja necessário alterar minha total
implementação. Isso não significa que eu preciso alterar minha add
implementação. Se algum goober os juntou em um único método, agora estou sentindo um pouco de dor desnecessária.
Quanta dor? Certamente eu poderia apenas copiar o código e criar um novo método quando necessário. Então, não é grande coisa, certo? Malarky! Se nada mais me custar um bom nome! É difícil encontrar bons nomes e não responde bem quando você brinca com o significado deles. Bons nomes, que tornam clara a intenção, são mais importantes do que o risco de você copiar um bug que, francamente, é mais fácil de corrigir quando o método tem o nome correto.
Portanto, meu conselho é parar de deixar reações bruscas a códigos semelhantes amarrar sua base de código em nós. Não estou dizendo que você é livre para ignorar o fato de que existem métodos e, em vez disso, copie e cole de maneira indesejada. Não, cada método deve ter um nome muito bom que apóie a única ideia de que se trata. Se sua implementação coincidir com a implementação de alguma outra boa idéia, agora, hoje, quem se importa?
Por outro lado, se você tiver um sum()
método que tenha uma implementação idêntica ou até mesmo diferente total()
, e mesmo assim, sempre que seus requisitos totais mudarem, você precisará mudar, sum()
então há uma boa chance de que sejam a mesma idéia sob dois nomes diferentes. O código não apenas seria mais flexível se fossem mesclados, como seria menos confuso de usar.
Quanto aos parâmetros booleanos, sim, é um cheiro desagradável de código. O fluxo de controle não apenas é um problema, mas também mostra que você cortou uma abstração em um ponto ruim. As abstrações devem tornar as coisas mais simples de usar, não mais complicadas. Passar bools para um método para controlar seu comportamento é como criar uma linguagem secreta que decide qual método você está realmente chamando. Ow! Não faça isso comigo. Dê a cada método seu próprio nome, a menos que você tenha alguma honestidade quanto ao polimorfismo .
Agora, você parece esgotado com a abstração. Isso é muito ruim, porque a abstração é uma coisa maravilhosa quando bem feita. Você usa muito sem pensar nisso. Toda vez que você dirige um carro sem ter que entender o sistema de pinhão e cremalheira, toda vez que usa um comando de impressão sem pensar nas interrupções do sistema operacional e toda vez que escova os dentes sem pensar em cada cerda individual.
Não, o problema que você parece estar enfrentando é uma abstração ruim. Abstração criada para servir a um propósito diferente das suas necessidades. Você precisa de interfaces simples em objetos complexos que permitem solicitar que suas necessidades sejam atendidas sem precisar entender esses objetos.
Ao escrever o código do cliente que usa outro objeto, você sabe quais são suas necessidades e o que você precisa desse objeto. Não faz. É por isso que o código do cliente possui a interface. Quando você é o cliente, nada lhe diz quais são suas necessidades, exceto você. Você cria uma interface que mostra quais são suas necessidades e exige que tudo o que lhe é entregue atenda a essas necessidades.
Isso é abstração. Como cliente, nem sei com o que estou falando. Eu apenas sei o que preciso disso. Se isso significa que você precisa encerrar algo para alterar sua interface antes de me entregar bem. Eu não ligo Apenas faça o que eu preciso fazer. Pare de complicar.
Se eu tiver que olhar dentro de uma abstração para entender como usá-la, a abstração falhou. Eu não deveria saber como isso funciona. Apenas isso funciona. Dê um bom nome e, se eu olhar para dentro, não ficarei surpreso com o que acho. Não me faça continuar olhando para dentro para lembrar como usá-lo.
Quando você insiste que a abstração funciona dessa maneira, o número de níveis por trás dela não importa. Contanto que você não esteja olhando para trás da abstração. Você está insistindo que a abstração está de acordo com suas necessidades, não se adaptando às suas. Para que isso funcione, deve ser fácil de usar, ter um bom nome e não vazar .
Essa é a atitude que gerou a injeção de dependência (ou apenas passe de referência, se você é da velha escola como eu). Funciona bem com prefere composição e delegação sobre herança . A atitude tem muitos nomes. O meu favorito é dizer, não pergunte .
Eu poderia afogar você em princípios o dia todo. E parece que seus colegas de trabalho já são. Mas eis o seguinte: ao contrário de outros campos de engenharia, esse software tem menos de 100 anos. Ainda estamos todos descobrindo. Portanto, não deixe que alguém com muitos livros intimidadores aprenda você a escrever códigos difíceis de ler. Ouça-os, mas insista em que fazem sentido. Não tome nada com fé. Pessoas que codificam de alguma maneira só porque lhes disseram que é assim, sem saber por que fazem as maiores bagunças de todas.