Como ter muitas variáveis ​​de instância leva ao código duplicado?

19

De acordo com a refatoração de padrões :

Quando uma classe está tentando fazer muito, muitas vezes aparece como muitas variáveis ​​de instância. Quando uma classe tem muitas variáveis ​​de instância, o código duplicado não pode ficar muito atrás.

Como ter muitas variáveis ​​de instância leva ao código duplicado?

q126y
fonte
2
Simplificando: nvariáveis ​​booleanas, por exemplo, criam um espaço de estado interno de 2^n. Na maioria das vezes, embora seu objeto não tenha tantos estados observáveis , mas como você amontoou todo esse estado em um único objeto, internamente ainda precisará lidar com todos eles.
biziclop

Respostas:

23

Ter muitas variáveis ​​de instância não está diretamente relacionada ao código duplicado ou vice-versa. Esta afirmação, nesta generalidade, é falsa. Pode-se lançar duas classes separadas sem código duplicado em uma classe - que produz uma nova classe com responsabilidades não separadas e muitas variáveis ​​de instância, mas ainda sem código duplicado.

Mas quando você encontra uma classe com muitas responsabilidades no código legado do mundo real, as chances são altas de o programador que o escreveu não se importar com o código limpo ou com os princípios do SOLID (pelo menos, não no momento em que ele escreveu esse código), então é Não é improvável que você encontre outro código que cheira a código duplicado.

Por exemplo, o antipadrão "copiar e colar reutilizar" geralmente é aplicado copiando um método antigo e fazendo algumas pequenas modificações nele, sem refatoração adequada. Às vezes, para fazer esse trabalho, é preciso duplicar uma variável de membro e modificá-la um pouco também. Isso pode resultar em uma classe com muitas variáveis ​​de instância (mais preciso: muitas variáveis ​​de instância com aparência muito semelhante). Em tal situação, as variáveis ​​de instância semelhantes talvez sejam um indicador para código repetido em outras partes da classe. No entanto, como você observou, este é um exemplo artificial e eu não concluiria uma regra geral.

Doc Brown
fonte
11

Muitas variáveis ​​de instância significam muito estado. Excesso de estado leva ao código duplicado que é apenas ligeiramente diferente para cada um dos estados.

Esta é uma aula concreta clássica clássica, fazendo muitas coisas que devem ser subclasses ou composições.

Encontre algumas classes que possuem muitas variáveis ​​de instância, você verá que elas mantêm demais o estado e têm muitos caminhos de código duplicados que são apenas levemente especializados para cada caso, mas tão complicados que não podem ser divididos em métodos reutilizáveis. Esta é uma das maiores fontes side effectstambém.

Há pelo menos uma exceção a isso que não se enquadra nessa categoria e é uma maneira fácil de corrigir isso. Immutableobjetos não têm esse problema, porque são um estado fixo, não há chances de gerenciamento de estado complicado ou efeitos colaterais.


fonte
7

A declaração que você cita deve ser vista em um contexto específico.

De acordo com minha experiência, não posso confirmar que "muitas variáveis ​​de instância em geral indicam código duplicado". Além disso, observe que isso pertence aos "odores de código" e há odores alegadamente contraditórios. Dê uma olhada aqui:

http://c2.com/cgi/wiki?CodeSmell

Divertidamente, você encontrará "muitas variáveis ​​de instância" com um cheiro de código tão bom quanto "poucas variáveis ​​de instância".

Mas há problemas com variáveis ​​de instância, sejam poucas ou muitas:

  1. Toda variável de instância pode significar algum tipo de status do objeto. Stati sempre precisa de um tratamento cuidadoso. Você deve garantir que cobriu todas as combinações possíveis de status para evitar comportamentos inesperados. Você deve sempre claramente agora: que status meu objeto tem agora? Desse ângulo, muitas variáveis ​​de instância podem indicar que a classe se tornou impossível de manter. Também pode indicar que uma classe faz muitos trabalhos, pois precisa de muitos status.

  2. Toda variável de instância exige que você mantenha a supervisão, quais métodos alteram a variável de que maneira. Então, de repente, você não conhece mais todos os cozinheiros que estão cozinhando. Um deles, programado cansadamente à noite, estraga sua sopa. Novamente: muitas dessas variáveis ​​levarão a códigos difíceis de penetrar.

  3. O outro lado: poucas variáveis ​​de instância podem causar que muitos métodos precisem manipular suas informações com muito trabalho e com muitos parâmetros. Você sente isso, se está dando a muitos de seus métodos um certo parâmetro igual e todos os métodos fazem algo muito semelhante com esse parâmetro. Nessa situação, seu código começará a inchar. Você acabará rolando várias telas para cima e para baixo, a fim de juntar algumas coisas simples. Aqui, uma refatoração pode ajudar: apresente uma variável de instância e uma entrada clara para ela. Em seguida, libere todos os métodos.

  4. Por último, mas não menos importante: se muitas variáveis ​​de instância de uma classe têm seus setter e getter, então isso pode indicar que outras classes não usam essa primeira classe da maneira certa. Há uma discussão sobre " Por que getters e setters são maus ". Em resumo, a idéia é que, se uma classe Rectangleoferecer alguns getX()e dezenas de outras classes usarem rectangle.getX(), você estará escrevendo um código que não é robusto contra o "efeito cascata" (em que medida uma alteração de código influencia outro código). Basta perguntar o que acontece se você alterar o tipo de intpara double? De acordo com essa discussão, muitas das rectangle.getX()chamadas deveriam ser de fato chamadas comorectanlge.calculateThisThingForMe(). Portanto, indiretamente, código duplicado pode surgir de muitas variáveis ​​de instância, pois muitas classes usam muitos getters e setters fazendo coisas muito semelhantes, ou seja, coisas copiadas, que devem ser melhor movidas dentro da classe.

Muitas ou poucas variáveis ​​de instância continuam sendo uma troca permanente, alterando os dois lados enquanto o software está crescendo.

peter_the_oak
fonte
A citação de R para P é muito geral e é por isso que eu gosto dessa resposta. Meu argumento é: se expormos propriedades suficientes, um cliente pode, e irá, pegá-las e escrever sua própria versão de uma determinada funcionalidade - o nº 4 acima. O problema pode ser tão profundo quanto a composição do objeto - consulte o item 2: vejo isso com muita frequência em nosso código. (a) "por que eles não usaram a classe <whatever> (para encurralar parte desse estado desorganizado)?" ou (b) "Por que eles não fizeram uma nova aula? Não consigo acompanhar tudo isso". E com certeza temos várias classes duplicando internamente a funcionalidade por falta de uma classe coerente.
Radarbob 02/12/2015
6

Simplificando: a fraca separação de preocupações no código, leva ao código que não é modular, leva à reutilização ruim, leva ao código duplicado.

Se você nunca tentar repetir a funcionalidade, não receberá código duplicado e muitas variáveis ​​de instância não serão um problema.

Se você tentar repetir a funcionalidade, o código monolítico, que não é modular, não poderá ser reutilizado. Faz muito e só pode fazer o que faz. Para fazer algo semelhante, mas não o mesmo, é "mais fácil" recortar e colar, em vez de quebrar o código monolítico. Os programadores de experiências sabem que o código duplicado é o caminho para o inferno.

Portanto, embora muitas variáveis ​​de instância em si não sejam a causa raiz do problema, é um forte "cheiro" que o problema está chegando.

A linguagem "não pode estar muito atrasada" é mais fraca do que dizer "certamente deve seguir", de modo que o autor não está afirmando que isso deve acontecer, mas acabará por acontecer; se você precisar reutilizar a funcionalidade, mas não puder, pois o código não é modular.

simbo1905
fonte