Cuándo usar una variable de instancia de objeto versus pasar un argumento al método

93

¿Cómo se decide entre pasar argumentos a un método o simplemente declararlos como variables de instancia de objeto que son visibles para todos los métodos del objeto?

Prefiero mantener las variables de instancia en una lista al final de la clase, pero esta lista se hace más larga a medida que crece mi programa. Me imagino que si una variable se pasa con la suficiente frecuencia, debería ser visible para todos los métodos que la necesiten, pero luego me pregunto, "si todo es público, ¡no habrá necesidad de pasar nada en absoluto!"

Ziggy
fuente
1
Si tiene ejemplos específicos, puede obtener respuestas más directamente útiles
brabster

Respuestas:

55

Como se refiere a variables de instancia, supongo que está trabajando en un lenguaje orientado a objetos. Hasta cierto punto, cuándo usar variables de instancia, cómo definir su alcance y cuándo usar variables locales es subjetivo, pero hay un par de reglas generales que puede seguir al crear sus clases.

  • Las variables de instancia generalmente se consideran atributos de una clase. Piense en estos como adjetivos del objeto que se creará a partir de su clase. Si los datos de su instancia se pueden usar para ayudar a describir el objeto, entonces probablemente sea seguro apostar que es una buena opción, por ejemplo, los datos.

  • Las variables locales se utilizan dentro del alcance de los métodos para ayudarles a completar su trabajo. Por lo general, un método debe tener el propósito de obtener algunos datos, devolver algunos datos y / o procesar / ejecutar un algoritmo en algunos datos. A veces, es útil pensar en las variables locales como formas de ayudar a que un método llegue de principio a fin.

  • El alcance de la variable de instancia no es solo para la seguridad, sino también para la encapsulación. No asuma que el "objetivo debe ser mantener todas las variables privadas". En casos de herencia, hacer variables como protegidas suele ser una buena alternativa. En lugar de marcar todos los datos de instancia como públicos, crea captadores / definidores para aquellos a los que se debe acceder al mundo exterior. No los ponga todos disponibles, solo los que necesita. Esto vendrá durante todo el ciclo de vida del desarrollo; es difícil de adivinar desde el principio.

Cuando se trata de pasar datos por una clase, es difícil decir que lo que está haciendo es una buena práctica sin ver algo de código. A veces, operar directamente en los datos de la instancia está bien; otras veces, no lo es. En mi opinión, esto es algo que viene con la experiencia: desarrollarás algo de intuición a medida que mejoren tus habilidades de pensamiento orientado a objetos.

Tom
fuente
Mi respuesta sería agregar esta respuesta a la respuesta de H-Man2 (de por vida). Debería ser un atributo de miembro si y solo si es un estado persistente del objeto. Es decir, el valor tiene sentido por sí mismo fuera del alcance de la pila de métodos actual.
David Rodríguez - dribeas
Mi reacción instintiva es estar de acuerdo con David y H-MAn2. Sin embargo, estoy leyendo "código limpio" de Robert c Martin y en el capítulo 3 refactoriza el código para mover algo de un parámetro de método a una variable miembro, porque tener muchos parámetros es malo. A fin de cuentas, supongo que si su clase solo tiene una sola responsabilidad, entonces la vida útil del objeto es la misma que la vida útil de ese cálculo, por lo que tal vez la respuesta real es que si tiene que hacer esta pregunta, ¿su clase es demasiado grande?
Andy
@ DavidRodríguez-dribeas ¿a qué te refieres con pila de métodos?
committedandroider
@committedandroider: si el valor sobrevive a la llamada de función actual
David Rodríguez - dribeas
46

Esto depende principalmente de la vida útil de los datos que almacena en la variable. Si los datos solo se utilizan durante un cálculo, páselos como parámetro. Si los datos están vinculados a la vida útil del objeto, utilice una variable de instancia.

Cuando su lista de variables se vuelve demasiado larga, tal vez sea un buen punto pensar en refactorizar algunas partes de la clase en una nueva clase.

H-Man2
fuente
21

En mi opinión, las variables de instancia solo son necesarias cuando los datos se utilizarán en todas las llamadas.

He aquí un ejemplo:

myCircle = myDrawing.drawCircle(center, radius);

Ahora permite que la imagen de la clase myDrawing use 15 funciones auxiliares para crear el objeto myCircle y cada una de esas funciones necesitará el centro y el radio. Todavía no deben establecerse como variables de instancia de la clase myDrawing. Porque nunca más serán necesarios.

Por otro lado, la clase myCircle necesitará almacenar tanto el centro como el radio como variables de instancia.

myCircle.move(newCenter);
myCircle.resize(newRadius);

Para que el objeto myCircle sepa cuál es su radio y centro cuando se realizan estas nuevas llamadas, deben almacenarse como variables de instancia, no solo pasarse a las funciones que las necesitan.

Básicamente, las variables de instancia son una forma de guardar el "estado" de un objeto. Si una variable no es necesaria para conocer el estado de un objeto, entonces no debería ser una variable de instancia.

Y en cuanto a hacer público todo. Podría hacerte la vida más fácil en este momento. Pero volverá a perseguirte. Por favor, no lo hagas.

ng.mangine
fuente
Sin embargo, puede definir mover para usar los parámetros (oldCenter, newCenter).
obeso pollo 13 de
4

EN MI HUMILDE OPINIÓN:

Si la variable forma parte del estado de la instancia, entonces debería ser una variable de instancia - classinstance HAS-A instanciavariable.

Si me encontraba pasando algo repetidamente a los métodos de una instancia, o si descubría que tenía una gran cantidad de variables de instancia, probablemente intentaría mirar mi diseño en caso de que me perdiera algo o hiciera una mala abstracción en alguna parte.

Espero eso ayude

brabster
fuente
3

Por supuesto, es fácil mantener una gran lista de variables públicas en la clase. Pero incluso intuitivamente, puede decir que este no es el camino a seguir.

Defina cada variable justo antes de utilizarla. Si una variable admite la función de un método específico, utilícela solo en el alcance del método.

Piense también en la seguridad, una variable de clase pública es susceptible a cambios no deseados del código "externo". Su objetivo principal debe ser mantener todas las variables privadas, y cualquier variable que no lo sea, debe tener una muy buena razón para serlo.

Acerca de pasar parámetros a lo largo de la pila, esto puede ponerse feo muy rápido. Una regla general es mantener las firmas de su método limpias y elegantes. Si ve muchos métodos que usan los mismos datos, decida si es lo suficientemente importante como para ser miembro de la clase y, si no lo es, refactorice su código para que tenga más sentido.

Todo se reduce al sentido común. Piense exactamente dónde y por qué está declarando cada nueva variable, cuál debería ser su función y, a partir de ahí, tome una decisión sobre en qué ámbito debería vivir.

Yuval Adam
fuente
A menudo desea que los métodos sean públicos para que pueda probarlos unitariamente.
obeso pollo 13 de