¿Prefiere miembros de la clase o pasar argumentos entre métodos internos?


39

Suponga que dentro de la parte privada de una clase hay un valor que es utilizado por múltiples métodos privados. ¿La gente prefiere tener esto definido como una variable miembro para la clase o pasarlo como argumento a cada uno de los métodos, y por qué?

Por un lado, pude ver que se argumenta que reducir el estado (es decir, las variables miembro) en una clase es generalmente algo bueno, aunque si el mismo valor se usa repetidamente en los métodos de una clase, parece que sería un ideal candidato a la representación como estado de la clase para que el código sea visiblemente más limpio, si nada más.

Editar:

Para aclarar algunos de los comentarios / preguntas que surgieron, no estoy hablando de constantes y esto no se relaciona con ningún caso en particular, sino simplemente con una hipótesis de la que estaba hablando con otras personas.

Ignorando el ángulo OOP por un momento, el caso de uso particular que tenía en mente era el siguiente (suponga pasar por referencia solo para hacer que el pseudocódigo sea más limpio)

int x
doSomething(x)
doAnotherThing(x)
doYetAnotherThing(x)
doSomethingElse(x)

Entonces, lo que quiero decir es que hay alguna variable que es común entre múltiples funciones; en el caso que tenía en mente, se debía al encadenamiento de funciones más pequeñas. En un sistema OOP, si estos fueran todos los métodos de una clase (por ejemplo, debido a la refactorización mediante la extracción de métodos de un método grande), esa variable podría pasarse a todos o podría ser un miembro de la clase.


1
¿Cómo se usa este valor? Es constante? ¿Cambia? ¿Está sujeto a cambios entre compilaciones?
Oded

Cuando las cosas se determinan automáticamente como iguales, es más fácil pensar que no importa. ¿Qué pasaría si tuviera una función que necesitara un valor ajustado (x) como x-1?
JeffO

Respuestas:


15

Si el valor es una propiedad de la clase, manténgalo en la clase; de ​​lo contrario, manténgalo fuera. No diseñas tus métodos de clase primero, primero diseñas sus propiedades. Si no pensó en poner esa propiedad dentro de la clase en primer lugar, probablemente haya una razón para eso.

Lo peor que puede hacer, en términos de escalabilidad, es cambiar su código para mayor comodidad. Más pronto que tarde, encontrará que su código está hinchado y duplicado. Sin embargo, debo admitir que a veces rompo esta regla ... La conveniencia es muy atractiva.


1
Estoy de acuerdo: el diseño / propósito original de la clase debería decirle si debería ser una variable miembro o un argumento. También vale la pena pensar en el ángulo de inyección de dependencia.
Martijn Verburg

14

Si realmente no necesita mantener el estado entre invocaciones (y aparentemente no lo hace, o no haría la pregunta), preferiría que el valor sea un argumento, en lugar de una variable miembro, porque un vistazo rápido en la firma del método le dice que usa el argumento, mientras que es un poco más difícil saber de inmediato qué variables miembro utiliza el método. Tampoco siempre es rápido determinar para qué son las variables miembro privadas.

Por lo tanto, normalmente no estaría de acuerdo en que el código que usa variables miembro es visiblemente más limpio, pero si las firmas del método se están yendo de las manos, podría hacer una excepción. Es una pregunta que vale la pena, pero no es algo en lo que dependerá el proyecto en ningún caso.


10

Gracias por hacer la pregunta, quería hacer esto también.

Cuando pensaba en esto, hay algunas ventajas en por qué pasarlo como argumento

  • es más fácil de probar -> más fácil de mantener (relacionado con el último punto)
  • no tiene efectos secundarios
  • es más fácil de entender

Veo claramente su punto, por ejemplo: uno está analizando un documento de Excel (usando la biblioteca de PDI, por ejemplo) y, en lugar de pasar la instancia de fila a cada método que necesita trabajar con esa fila, el autor tiene una variable miembro currentRowy trabaja con ella.

Yo diría que debería haber un nombre para este antipatrón, ¿verdad? (no incluido aquí )


¿Qué antipatrón quieres decir?
Vahid Ghadiri

En resumen, tener una variable miembro solo para compartir parámetros entre dos (o más) llamadas a funciones ...
Betlista

1

Quizás debería extraer una nueva clase que contenga todos los métodos que comparten ese valor. Por supuesto, el método de más alto nivel será público en la nueva clase. Puede ser útil exponer ese método para realizar pruebas.

Si tiene dos o más temporarios que siempre se pasan juntos, entonces seguramente debería extraer una nueva clase.


1

¿La gente prefiere tener esto definido como una variable miembro para la clase o pasarlo como argumento a cada uno de los métodos, y por qué?

Si entiendo lo que está preguntando: los métodos en una clase están, por definición, al tanto de los detalles de la implementación, por lo que no tendría reparos en usar cualquier miembro directamente de cualquier método.

Por un lado, pude ver que se argumenta que reducir el estado (es decir, las variables miembro) en una clase es generalmente algo bueno ...

No hay nada de malo en declarar un private static final para definir constantes. El compilador podrá usar el valor al considerar algunas optimizaciones, y al ser constantes, en realidad no agregan estado a la clase.

aunque si el mismo valor se usa repetidamente en todos los métodos de una clase ...

Ser capaz de referirse a él simbólicamente (por ejemplo, BLRFL_DURATION) y no tener que agregar argumentos adicionales a sus métodos hará que su código sea más legible y por lo tanto más fácil de mantener.


0

Si el valor no cambia, es, por definición, una constante y debe encapsularse dentro de la clase. En tal caso, no se considera que afecte el estado de un objeto. No conozco tu caso, pero pienso en algo como PI en trigonometría. Si intenta pasar un argumento de tal constante, podría exponer el resultado al error si el cliente pasa el valor incorrecto o un valor que no tiene la misma precisión que los métodos esperados.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.