Eu passei a acreditar em algo sobre a refatoração que eu não vi mencionado aqui, eu sei que há muitas respostas aqui, mas eu acho que isso é novo.
Eu tenho sido um refactorer implacável e um strong crente em DRY desde antes dos termos surgiram. Principalmente porque eu tenho dificuldade em manter uma grande base de código na minha cabeça e em parte porque gosto de codificação DRY e não gosto de nada sobre codificação C & P, na verdade é doloroso e terrivelmente lento para mim.
A questão é que insistir em DRY me deu muita prática em algumas técnicas que raramente vejo outras pessoas usarem. Muitas pessoas insistem que o Java é difícil ou impossível de fazer o DRY, mas na verdade eles simplesmente não tentam.
Um exemplo de muito tempo atrás é semelhante ao seu exemplo. As pessoas tendem a pensar que a criação de GUIs Java é difícil. Claro que é se você codifica assim:
Menu m=new Menu("File");
MenuItem save=new MenuItem("Save")
save.addAction(saveAction); // I forget the syntax, but you get the idea
m.add(save);
MenuItem load=new MenuItem("Load")
load.addAction(loadAction)
Qualquer um que pense que isso é uma loucura está absolutamente certo, mas não é culpa do Java - o código nunca deve ser escrito dessa forma. Essas chamadas de método são funções destinadas a serem agrupadas em outros sistemas. Se você não consegue encontrar tal sistema, construa-o!
Você obviamente não pode codificar assim, então você precisa dar um passo atrás e ver o problema, o que esse código repetido realmente está fazendo? Ele está especificando algumas strings e seu relacionamento (uma árvore) e juntando as folhas dessa árvore às ações.
Então, o que você realmente quer é dizer:
class Menu {
@MenuItem("File|Load")
public void fileLoad(){...}
@MenuItem("File|Save")
public void fileSave(){...}
@MenuItem("Edit|Copy")
public void editCopy(){...}...
Uma vez que você tenha definido seu relacionamento de forma sucinta e descritiva, então você escreve um método para lidar com ele - nesse caso, você faz uma iteração sobre os métodos da classe passada e constrói uma árvore e usa isso para construa seus menus e ações, bem como (obviamente) exibir um menu. Você não terá nenhuma duplicação, e seu método é reutilizável ... e provavelmente mais fácil de escrever do que um grande número de menus teria sido, e se você realmente gosta de programar, você se divertiu muito mais. Isso não é difícil - o método que você precisa escrever é, provavelmente, menos linhas do que criar seu menu à mão!
A coisa é que, para fazer isso bem, você precisa praticar muito. Você precisa ser bom em analisar exatamente quais informações exclusivas estão nas partes repetidas, extrair essas informações e descobrir como expressá-las bem. Aprender a usar ferramentas como a análise de strings e anotações ajuda muito. Aprender a ser muito claro sobre relatórios de erros e documentação também é muito importante.
Você adquire prática "Free" simplesmente codificando bem - as chances são de que, uma vez que você fique bom nisso, você verá que codificar algo DRY (incluindo escrever uma ferramenta reutilizável) é mais rápido do que copiar e colar e todos os erros. , erros duplicados e mudanças difíceis que o tipo de codificação causa.
Eu não acho que seria capaz de aproveitar meu trabalho se não praticasse técnicas de DRY e construísse ferramentas o máximo que pudesse. Se eu tivesse que fazer um corte no pagamento para não ter que copiar e colar programação, eu aceitaria isso.
Então, meus pontos são:
- Copiar & Colar custa mais tempo, a menos que você não saiba como refatorar bem.
- Você aprende a refatorar bem fazendo isso - insistindo no DRY mesmo nos casos mais difíceis e triviais.
- Você é um programador, se precisar de uma pequena ferramenta para criar seu código DRY, crie-o.