2012-08-04 14 views
10

me di cuenta de que, incluso cuando se paga el respeto al principio de la responsabilidad individual de OOD, a veces las clases todavía crecen grandes. A veces, el acceso a las variables miembro directamente en los métodos se siente como tener un estado global, y existen muchas cosas en el alcance actual. Con solo mirar el método en el que se está trabajando actualmente, ya no es posible determinar de dónde provienen las variables inviduales disponibles en el ámbito actual.¿Tiene acceso directo a las variables miembro o pasa como parámetro?

Cuando se trabaja junto con un amigo últimamente, me di cuenta de que escribo código mucho más prolija que él, porque yo paso variables miembro todavía como parámetros en cada método único.

¿Es esta una mala práctica?

edición: ejemplo:

class AddNumbers { 
public: 
    int a, b; 
    // ... 
    int addNumbers { 
     // I could have called this without arguments like this: 
     // return internalAlgorithmAddNumbers(); 
     // because the data needed to compute the result is in members. 
     return internalAlgorithmAddNumbers(a,b); 
    } 

private: 
    int internalAlgorithmAddNumbers(int sum1, int sum2) { return sum1+sum2; } 
}; 
+1

Si sus clases son demasiado grandes, divídalas. Si tiene una variable miembro, úselo. Si no está utilizando variables miembro en un método, probablemente debería ser 'estático', pero hacer eso suena extraño. – Flexo

+1

Disculpe, parece que tengo un ligero problema con su inglés. ¿Usted pasa las variables miembro como parámetros? ¿Variables de miembros públicos? O nuevos valores para estas variables miembro? Estoy un poco confundido. – ATaylor

+0

Perdón por no haber sido claro en eso. Cuando implemento un algoritmo, por lo general vuelvo a iterar los parámetros que toma en la firma del método, aunque los datos que el algoritmo requiere se pueden extraer directamente de las variables miembro. Supongamos que tiene una clase, que agrega dos números, y tiene los 2 números a y b como variables de miembro. Entonces, en lugar de tener un método de adición privado con cero parámetros, aún definiría una función tomando 2 argumentos int. De esta manera, podría reutilizar el algoritmo también fuera de una clase. – Tom

Respuesta

5

Si una clase tiene variables miembro, usarlos. Si desea pasar parámetros explícitamente, haga que sea una función gratuita. Al pasar las variables de miembro no solo hace que el código sea más detallado, también viola las expectativas de las personas y hace que el código sea difícil de entender.

Todo el propósito de una clase es crear un conjunto de funciones con un estado compartido implícitamente pasado. Si esto no es lo que quieres hacer, no uses una clase.

2

Sí, definitivamente una mala práctica. Pasar una variable miembro a una función miembro tiene ningún sentido en absoluto, desde mi punto de vista. Tiene varias desventajas:

  1. código Disminución legibilidad
  2. Costo en términos de actuaciones para copiar el parámetro en la pila

Eventualmente convertir el método a una función simple, puede tener sentido. De hecho, desde un punto de vista del rendimiento, la llamada a la función no miembro es en realidad más rápida (no es necesario desreferenciar este puntero).

EDITAR:

Responder a su comentario. Si la función puede realizar su trabajo solo con unos pocos parámetros pasados ​​explícitamente, y no necesita ningún estado interno, probablemente no haya ninguna razón para declarar que tiene una función de miembro. Use una llamada de función estilo C simple y pase los parámetros a ella.

+0

Ese es exactamente mi punto en la pregunta. Como creo que en realidad aumenta la legibilidad del código, no aparecen nombres externos mágicos en su ámbito local. Hace mucho tiempo me enseñaron que las variables globales son de muy mal estilo, y acceder a una variable miembro a veces se siente como usar variables globales. Está accediendo a algo que no está en su alcance local, ni se transfiere desde el exterior como parámetro. – Tom

+1

@Tom - los miembros de la clase no son globales; son explícitamente locales para la instancia de la clase con la que estás trabajando. Tu clase es una encapsulación de un estado pequeño y relacionado. Si no lo son, entonces tienes problemas de diseño más grandes que no se pueden reparar de esta manera. En el ejemplo que diste, estaría tentado de hacer que tus instancias sean inmutables incluso. – Flexo

1

entiendo el problema, después de haber tenido que mantener grandes clases en el código no lo hice originalmente autor. En C++ tenemos la palabra clave const para ayudar a identificar los métodos que no cambian el estado:

void methodA() const; 

uso de esta ayuda de mantenimiento, ya que podemos ver si un método puede cambiar el estado de un objeto.

En otros idiomas que no tienen este concepto prefiero ser claro acerca de si voy a cambiar el estado de la variable de instancia por cualquiera que tenga que pasar por referencia en el cambio o devolución

this->mMemberVariable = this->someMethod(); 

En lugar de

void someMethod() 
{ 
    this->mMemberVariable = 1; // change object state but do so in non transparent way 
} 

He descubierto a lo largo de los años que esto facilita el mantenimiento del código.

Cuestiones relacionadas