2012-03-15 13 views
5

Tengo un jar común que usa un poco de unmarshaling de un objeto String. El método debe actuar de manera diferente según la aplicación a la que se llame, ¿cómo puedo hacer eso además del hecho de que puedo identificar la aplicación al intentar cargar alguna clase única que tiene (no me gusta)? ¿Hay algún patrón de diseño que resuelva este problema?¿Cómo cambiar el comportamiento de un método según la aplicación que lo está llamando?

+12

El "patrón de diseño" que _should_ a utilizar es simplemente ¡no tener un cambio en el comportamiento del método basado en factores externos! El comportamiento diferente debería ser un método diferente. – cdeszaq

+4

I segundo comentario de @ cdeszaq. O bien es un contenedor ** común ** con funcionalidad común, o tiene un comportamiento ** particular ** para aplicaciones particulares. Si está tratando de separar el código común en un contenedor externo, esto es bueno. Pero también debe escribir ese código como si no supiera quién lo llamará (evite referencias circulares lógicas en su código). – MicSim

Respuesta

3

Como ya he aludido en mi comentario, el mejor que hay que hacer es romper ese súper método para arriba en diversos métodos que encapsulan los comportamientos específicos, y probablemente también otro método (utilizado por toda la aplicación específica unos) que se ocupa de los comportamientos comunes.

Lo más importante que debe recordar es que comportamiento importa. Si algo se comporta de manera diferente en diferentes escenarios, una aplicación de llamada efectivamente no puede usar ese método porque no tiene ningún control sobre lo que sucede.

Si todavía realmente quieren tener un único método que todas las aplicaciones de llamada que se comporta de manera diferente en cada uno, puede hacerlo, usando un cierto patrón de diseño, de una manera que tiene sentido y es mantenible El patrón se llama "Template Method".

La idea general de esto es que la aplicación de llamada transmite un poco de lógica que el método llamado envuelve y llama cuando lo necesita. Esto es muy similar a la programación funcional o la programación que utiliza cierres, donde está pasando fragmentos de la lógica como si se tratara de datos. Si bien Java propiamente no admite cierres, otros lenguajes basados ​​en JVM como Groovy, Scala, Clojure, JRuby, etc. hacen cierres de soporte.

Esta misma idea general es muy poderosa en ciertas circunstancias, y puede aplicar en su caso, sino una cuestión de este tipo requiere un conocimiento muy íntimo del dominio de la aplicación y de la arquitectura y en realidad no hay suficiente información en su pregunta publicada cavar demasiado más profundo.

2

En realidad, creo que una buena solución orientada a OO es, en el contenedor común, tener una clase base y varias clases derivadas. La clase base contendría la lógica común para el método que se llama, y ​​cada clase derivada contendría un comportamiento específico.

Así, en su frasco, es posible que tenga la siguiente:

public abstact class JarClass { 
    public method jarMethod() { 
     //common code here   
    } 
} 

public class JarClassVersion1 extends JarClass { 
    public method jarMethod() { 
     // initiailzation code specific to JarClassVerion1 
     super.jarMethod(); 
     // wrapup code specific to JarClassVerion1 
    } 
} 

public class JarClassVersion2 extends JarClass { 
    public method jarMethod() { 
     // initiailzation code specific to JarClassVerion2 
     super.jarMethod(); 
     // wrapup code specific to JarClassVerion2 
    } 
} 

En cuanto a cómo funciona la persona que llama, si está dispuesto a diseñar su código para que el conocimiento de la que deriva la clase de usar reside con la persona que llama, entonces, obviamente, solo hace que la persona que llama cree la clase derivada apropiada y llame a jarMethod.

Sin embargo, tomo su pregunta, usted desea saber qué clase utilizar para residir en el contenedor. En ese caso, hay varias soluciones. Pero una bastante fácil es definir un método de fábrica dentro del contenedor que crea la clase derivada apropiada.Por lo tanto, dentro de la JarClass abstracta, es posible definir el siguiente método:

public static JarClass createJarClass(Class callerClass) { 
    if (callerClass.equals(CallerClassType1.class)) { 
     return new JarClassVersion1(); 
    } else if (callerClass.equals(CallerClassType2.class)) { 
     return new JarClassVersion1(); 
     // etc. for all derived classess 
} 

Y entonces la persona que llama simplemente hacer lo siguiente:

JarClass.createJarClass(this.getClass()).jarMethod(); 
Cuestiones relacionadas