2011-09-07 9 views
5

Encontré este código en el que tres controladores usan una llamada a un método, por ejemplo ClassA.search (a, b, flag). Esta es una versión simplificada del método:¿Es esta una buena manera de reutilizar/compartir un método?

public List<Result> search(Object a, Object b, boolean flag) { 
    //do some code logic here, common to the 3 controllers 
    //at the middle there is: 
    if (flag) { 
     //code that affects 2 Controllers 
    } else { 
     //code affects only 1 
    } 
    //some more common code 
    //some more code with the flag if else 
} 

¿Es esta una buena idea porque el código se reutiliza? ¿O existe una mejor manera de poder hacer la reutilización del código pero no introducir este indicador para la personalización del código del llamador del método (cliente) (como dividirlo en 3 métodos diferentes pero aún así poder declarar un método refactorizado de código común)?

Respuesta

6

En primer lugar, el extracto comentado líneas con funciones:

public void search(Object a, Object b, boolean flag) 
{ 
    commonToThree(); 
    if (flag) 
    { 
     affectTwoControllers(); 
    } 
    else 
    { 
     affectsOnlyOne(); 
    } 
    alsoCommon(); 
} 

Ahora deshacerse de flag argumento booleano, que es un olor código:

public void searchWithTrueFlag(Object a, Object b) { 
    commonToThree(); 
    affectTwoControllers(); 
    alsoCommon(); 
} 

public void searchWithFalseFlag(Object a, Object b) { 
    commonToThree(); 
    affectsOnlyOne(); 
    alsoCommon(); 
} 
+0

Estoy de acuerdo con esto siempre que no termine convirtiendo variables locales en campos para que funcione. –

+0

¿Por qué las variables locales son malas? Si el estado que tiene que pasar una y otra vez a través de los parámetros es tan significativo, cree un objeto de una sola vez con el estado inicializado en los campos finales en el constructor y utilícelo solo una vez. Función en esteroides ;-). –

+0

Eso es cierto; sin embargo, agregar una clase con campos (¿y un constructor?) Es mucho trabajo para evitar una bandera. ;) –

3

Es bueno, pero no excelente. Un booleano tiene sentido, pero si comienzas a agregar más, no estás yendo en la dirección correcta.

No siempre es posible, pero por lo general se obtiene un mejor código que hacer:

functionOne: 
    sharedCodeOne() 
    specificCode 
    sharedCodeTwo() 

functionTwo: 
    sharedCodeOne() 
    specificCode 
    sharedCodeTwo() 

Como siempre, es difícil hacer afirmaciones generalizadas: Obviamente, esto no siempre es posible/práctico.

+1

+1: Esto es bueno si las tres secciones del código no comparten ninguna variable local.(o solo comparta un número pequeño) –

+1

@Peter: estoy totalmente de acuerdo. Creo que es en realidad y es una ventaja de este enfoque que lo lleve a reducir el número y el alcance de las variables locales. (Aunque algunas personas tienden a convertirlos en campos de la clase que los incluye, haciendo un lío de cosas) –

+1

@Arnout Engelen, estoy de acuerdo en que agregar campos para hacer que esto funcione no es una buena idea. –

0

Es una forma relativamente simple de hacerlo. Hay alternativas, pero es probable que sean más complejas. (Como pasar un visitante o llamar a un método del controlador para decir qué hacer para ese controlador)

Este enfoque es mejor si comparte variables locales entre las tres secciones de código y tendría que usar campos en su lugar.

0

Me gustaría tener un enfoque diferente tratando de responder esta pregunta de una manera general:

El objetivo principal debe ser limpiar el código. Lo que es exactamente esto, por supuesto, depende del caso específico. Pero seguro, es malo tener código de copiar y pegar en varios lugares, ya que esto requiere cambiar varios lugares si tiene que haber cambios. Además, es malo intentar extraer partes comunes donde más de una parte esté usando ellos en todas las circunstancias.

Siempre imagina a alguien que tiene que leer tu código (o tienes que hacerlo dentro de unas semanas) y tener que entender lo más rápido posible lo que está pasando allí. Entonces, depende del caso especial, si es mejor copiar algunas líneas o extraerlas de un método común.

Un indicador no es per se malo, pero en realidad no es algo que deba usarse demasiado en los métodos de Java. A menudo, una situación de este tipo se puede resolver de manera agradable sobrecargando un método y usando uno en el otro, de modo que el caso común se haga en uno y la adición especial en el otro. Alternativamente, puede tener varios submétodos y componer su método con varias llamadas a ellos, pero esto solo tiene sentido, si no necesita pasar demasiados parámetros.

Una regla (completamente subjetiva, pero basada en las lecciones aprendidas de muchos proyectos) Puedo darte: Favorecer las implementaciones concretas ober acercamientos genéricos. Pueden dar como resultado más código y parecer menos inteligentes, pero son mucho más fáciles de entender, extender y depurar.

Cuestiones relacionadas