¿Cómo tener demasiadas variables de instancia conduce a un código duplicado?

19

De acuerdo con Refactoring to Patterns :

Cuando una clase intenta hacer demasiado, a menudo aparece como demasiadas variables de instancia. Cuando una clase tiene demasiadas variables de instancia, el código duplicado no puede estar muy lejos.

¿Cómo tener demasiadas variables de instancia conduce a un código duplicado?

q126y
fuente
2
En pocas palabras: las nvariables booleanas, por ejemplo, crean un espacio de estado interno de 2^n. La mayoría de las veces, aunque su objeto no tiene tantos estados observables , pero debido a que ha agrupado todo ese estado en un solo objeto, internamente aún tiene que manejarlos a todos.
biziclop

Respuestas:

23

Tener demasiadas variables de instancia no está directamente relacionado con el código duplicado, o viceversa. Esta afirmación, en esta generalidad, es falsa. Uno puede lanzar dos clases separadas sin código duplicado en una clase, lo que produce una nueva clase con responsabilidades no separadas y demasiadas variables de instancia, pero aún sin código duplicado.

Pero cuando encuentra una clase con demasiadas responsabilidades en el código heredado del mundo real, es muy probable que al programador que la escribió no le importó el código limpio o los principios SÓLIDOS (al menos, no en el momento en que escribió ese código), por lo que es No es improbable que encuentre otros olores de código como código duplicado allí.

Por ejemplo, el antipatrón "copiar-pegar reutilizar" a menudo se aplica copiando un método antiguo y haciendo algunas modificaciones leves, sin la refactorización adecuada. A veces, para que esto funcione, uno tiene que duplicar una variable miembro y modificarla también un poco. Esto podría dar como resultado una clase con demasiadas variables de instancia (más preciso: demasiadas variables de instancia de aspecto muy similar). En tal situación, las variables de instancia similares pueden ser un indicador de código repetido en otra parte de la clase. Sin embargo, como notó, este es un ejemplo artificial, y no concluiría una regla general de él.

Doc Brown
fuente
11

Demasiadas variables de instancia significan demasiado estado. Demasiado estado conduce a un código duplicado que es solo ligeramente diferente para cada uno de los estados.

Esta es una clase clásica de concreto simple que hace demasiadas cosas que deberían ser subclases o composiciones.

Busque algunas clases que tengan demasiadas variables de instancia, verá que mantienen demasiado estado y tienen muchas rutas de código duplicadas que solo están ligeramente especializadas para cada caso, pero tan complicadas que no pueden dividirse en métodos reutilizables. Esta es una de las mayores fuentes de side effectstambién.

Hay al menos una excepción a esto que no entra en esta categoría y es una manera fácil de remediar esto. ImmutableLos objetos no tienen este problema, ya que son un estado fijo, no hay ninguna posibilidad de administración de estado complicado o efectos secundarios.


fuente
7

La declaración que usted cita está destinada a verse en un contexto específico.

Según mi experiencia, no puedo confirmar que "muchas variables de instancia en general indican código duplicado". Además, tenga en cuenta que esto pertenece a los "olores de código", y supuestamente hay olores contradictorios. Echa un vistazo aquí:

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

Divertidamente, encontrará que "demasiadas variables de instancia" es un olor a código tan bueno como "muy pocas variables de instancia".

Pero hay problemas con las variables de instancia, ya sean muy pocas o demasiadas:

  1. Cada variable de instancia puede significar algún tipo de estado del objeto. Stati siempre necesita un tratamiento cuidadoso. Debe asegurarse de haber cubierto todas las combinaciones posibles de estadísticas para evitar comportamientos inesperados. Siempre debes tener claro ahora: ¿qué estado tiene mi objeto ahora? Desde este ángulo, muchas variables de instancia pueden indicar que la clase se ha vuelto imposible de mantener. También puede indicar que una clase realiza demasiados trabajos, ya que necesita muchos stati.

  2. Cada variable de instancia requiere que usted supervise, qué métodos alteran la variable de qué manera. Entonces, de repente, ya no conoces a todos los cocineros que están cocinando. Uno de ellos, programado con cansancio a altas horas de la noche, estropeará su sopa. Nuevamente: demasiadas de esas variables conducirán a un código difícil de penetrar.

  3. El otro lado: muy pocas variables de instancia pueden causar que muchos métodos deben manejar su información con demasiado trabajo y con demasiados parámetros. Sientes esto si le estás dando a muchos de tus métodos un cierto parámetro igual, y todos los métodos hacen algo muy similar con este parámetro. En esa situación, su código comenzará a hincharse. Terminarás desplazando muchas pantallas hacia arriba y hacia abajo para juntar algunas cosas simples. Aquí, una refactorización puede ayudar: introduzca una variable de instancia y una entrada clara. Luego, libera todos los métodos.

  4. Por último, pero no menos importante: si muchas variables de instancia de una clase tienen su setter y getter cada una, entonces puede indicar que otras clases no usan esta primera clase de la manera correcta. Hay una discusión sobre " Por qué los captadores y los colocadores son malvados ". En resumen, si una clase Rectangleofrece algo getX()y usan docenas de otras clases rectangle.getX(), entonces está escribiendo código que no es robusto contra el "efecto dominó" (en qué medida un cambio de código influye en otro código). Simplemente pregunte qué sucede si cambia el tipo de inta double. Según esta discusión, muchas de las rectangle.getX()llamadas deberían ser llamadas comorectanlge.calculateThisThingForMe(). Por lo tanto, de manera muy indirecta, el código duplicado podría surgir de muchas variables de instancia, ya que muchas clases utilizan muchos getters y setters que hacen cosas muy similares, es decir, cosas copiadas, que deberían moverse mejor dentro de la clase.

Muchas o pocas variables de instancia siguen siendo una compensación permanente, alterando ambas formas mientras el software está creciendo.

peter_the_oak
fuente
La cita de R a P es demasiado general, por eso me gusta esta respuesta. Mi conclusión es: si exponemos suficientes propiedades que un cliente puede, y tomará, y escribirá su propia versión de una funcionalidad dada - # 4 arriba. El problema puede ser tan profundo como la composición del objeto; consulte el n. ° 2: veo esto con demasiada frecuencia en nuestro código. (a) "¿por qué no usaron la clase <whatever> (para acorralar parte de este estado desorganizado)?" o (b) "¿Por qué no hicieron una nueva clase? No puedo hacer un seguimiento de todo". Y efectivamente, tenemos varias clases que duplican la funcionalidad internamente por falta de una clase coherente.
radarbob
6

En pocas palabras: mala separación de las preocupaciones dentro del código, conduce a un código que no es modular, conduce a una mala reutilización, conduce a un código duplicado.

Si nunca intenta repetir la funcionalidad, no obtendrá código duplicado, y muchas variables de instancia no serán un problema.

Si intenta repetir la funcionalidad, entonces el código monolítico, que no es modular, no puede reutilizarse. Hace demasiado y solo puede hacer lo que hace. Para hacer algo similar, pero no igual, es "más fácil" cortar y pegar, en lugar de romper el código monolítico. Los programadores de experiencias saben que el código duplicado es el camino al infierno.

Entonces, aunque muchas variables de instancia en sí mismas no son la causa raíz del problema, es un fuerte "olor" que el problema está llegando.

El lenguaje "no puede estar muy lejos" es más débil que decir "seguramente debe seguir", por lo que el autor no afirma que deba suceder sino que eventualmente sucederá; si necesita reutilizar la funcionalidad pero no puede porque el código no es modular.

simbo1905
fuente