2012-04-26 15 views
8

Estoy trabajando en una aplicación empresarial compleja codificada en Java impulsada por composiciones de objetos complejos. Por ejemplo: En un escenario en particular, para llevar a cabo una acción este es el flujo:¿Es una buena práctica escribir métodos que devuelvan el vacío?

login() -> 
Followed by defined sequence of 10 to 20 method calls in different classes -> 
Followed by a logout() 

Dentro del marco, casi todas las acciones, incluyendo la conexión, desconexión, y muchos de los 10 a 20 llamadas a métodos tienen sin retorno tipos. Cualquier comportamiento erróneo es manejado por el marco. Digamos, en el inicio de sesión

public void login(){ 
try{ 
//login actions 
//chained sequence of calls 

}catch(){ 
// framework handling exceptions and other rollback options 
} 
} 

Las acciones intermedias de 10 a 20 son llamadas a métodos sobre diferentes objetos en diferentes niveles de jerarquía del marco.

Una clase al azar se vería así:

class someobject{ 

def variable 

void action1(){ do something on variable } 
void action2(){ do something on variable } 
... 
} 

Los cambios de variables de estado a menudo y estas acciones tienen una secuencia definida sólo por el marco que me resulta muy molesto.

Yo diría, Probablemente, si hubiera tipos de devolución apropiados en absoluto o al menos algunos de estos métodos, como en decir boolean en el caso de login(), la vida sería mucho más fácil. Debido a esta estrecha adherencia a una serie de funciones de retorno de espacios vacíos, me resulta difícil realizar una depuración para comprender el flujo y también las pruebas unitarias se convirtieron en una pesadilla para mí.

Así que ahora, tengo la impresión de que siempre es mejor escribir funciones que devuelvan algo, especialmente cuando hay una cadena de acciones implicadas. Entonces, ¿es esto una presunción segura? Me gustaría tomar sus opiniones sobre esto. Corrígeme si estoy equivocado.

+0

Lo que explique aquí parece que le falta un diseño adecuado de componentes. El enfoque dará como resultado un 'código de spagetti' irrecuperable. Puede que necesites introducir algunas capas intermedias ... – home

Respuesta

4

La capacidad de comprobación más básica de un método es a través de su código de retorno. En el caso de login necesita (como ha indicado) poder probar si ya ha iniciado sesión, y el retorno boolean es la forma obvia. De lo contrario, debe verificar alguna propiedad, que parece innecesariamente no atómica y compleja (aunque podría ser necesaria por otros motivos).

Para mí, este argumento se extiende a cualquier método significativo. El uso de códigos de retorno void es bastante común, pero más como resultado de viejos hábitos que por buenas razones de diseño. Sin embargo, el establecimiento de propiedades simples es un contraejemplo, y estoy seguro de que hay otros.

+1

Si eres un fanático de la programación funcional (que yo soy), iría un paso más allá y diría que los métodos vacíos son un signo de estado mutable, lo cual es malo. –

2

Cuando un método opera con datos locales en la clase, un método de vacío es perfectamente razonable, siempre que modele algún "comportamiento" que tenga sentido en el contexto de la clase. Por ejemplo, si tiene una SpecialSortedList que clasifica su contenido, es decir, myList.sort(), el método sort() sería nulo, ya que modela algún comportamiento asociado con SpecialSortedList.

Si un método no opera en datos locales dentro de una clase, es decir, exceptúa sus datos a través de parámetros y devuelve algún dato (es decir, no confía en datos locales), es una buena práctica declararlo como estático e incluso moverlo a una utilidad o clase auxiliar.

2

En mi opinión no es necesario siempre devolver algo en la cadena de acciones. Depende totalmente de sus requisitos. Es decir, en el método de autenticación de inicio de sesión, es mejor devolver el resultado booleano para simplificar. Si la cadena de acciones es independiente de una y otra, entonces, en mi opinión, no hay necesidad de devolver nada que no vaya a ser utilizado por ninguna acción. Por lo tanto, si el resultado de una acción afecta la siguiente acción, debe devolver algo para simplificar y probar, de modo que pueda trazar directamente desde la salida del método que está causando problemas.Una vez que se identifica el método, puede verificar el método específico que se identifica. Entonces, básicamente, todo depende de tus requisitos. Si sus requisitos se manejan mejor sin devolver algo, entonces debe hacerlo. También debe seguir las mejores prácticas o patrones de diseño para la efectividad que será mejor para todas las situaciones y puede deshacerse de crear desorden al final. Es solo mi opinión.

0

Cada vez más, prefiero devolver algo así como un código de estado en lugar de vacío. Esto hace un par de cosas:

  1. que permite que el código de la llamada a su función para saber qué hacer a continuación (por ejemplo, si la operación ha fallado, entonces el código de llamada puede tener que hacer algo diferente que si la operación tuvo éxito)
  2. Es más fácil de probar y depurar (como usted menciona). Empecé a creer que escribir código para probar es una de las mejores maneras de garantizar la calidad del código (suponiendo, por supuesto, que realmente lo pruebes). Las funciones vacías son difíciles de probar.

Mi preferencia es, siempre que sea posible, tener la mayoría de las funciones tomar parámetros, devolver una respuesta y no cambiar ninguna variable de clase. Como mencionó Jaco, estos pueden declararse estáticos e incluso moverse a una clase de utilidad. Entonces puede hacer que algunas funciones del controlador hagan uso de las funciones que devuelven valores.

0

sin dividir la respuesta como 2 partes:

  • Cuando está regresando "vacío" útil -

    Si el método devuelve un valor sólo para indicar un estado incorrecto/excepción, debería estar volviendo "vacío". La Excepción debe encargarse de manejar todos los escenarios de error en lugar de, digamos, un valor de retorno "booleano". Ahora, el código de llamada necesita validar nuevamente tanto el booleano como la excepción. Si solo arrojó Exception, entonces es mucho más fácil & más claro para el código de llamada.

  • Cuando está volviendo vacío no tan útil -

    Si el método lleva a cabo cualquier operación y devuelve un valor como resultado, a continuación, "vacío" no debe ser devuelto, el tipo de resultado relevante (boolean/entero/object etc.) debe ser devuelto.

En general, el valor de retorno debe corresponder real acerca de si el método devuelve algo o no. No debería corresponder a si el método se ejecutó correctamente (bueno, se supone que debe). Todos los escenarios de validación/excepción de entrada deben manejarse mediante el lanzamiento de las excepciones correspondientes. Ejemplo, lanzar IllegalArgumentException cuando la entrada no es válida, en lugar de devolver "boolean" diciendo que el método no se ejecutó.

Cuestiones relacionadas