2009-09-30 8 views
5

Necesito crear una clase que será responsable del procesamiento del conjunto de resultados, pero puede suceder que se utilicen diferentes algoritmos para procesar ese conjunto de resultados.Patrones de fábrica y estrategia

Soy consciente de las siguientes opciones:

1) patern utilizar la estrategia, a continuación es pseudo código:

interface Strategy { 
    processResultSet(ResultSet rs); 
} 

class StrategyA implements Strategy { 
    processResultSet(ResultSet rs); 
} 

class StrategyB implements Strategy { 
    processResultSet(ResultSet rs); 
} 

clase de contexto contendrá referencia a la estrategia y el cliente debe pasar a la ejecución de la estrategia de crear objeto de contexto, es decir,

class Context { 
    private Strategy strategy; 

    public Context(Strategy strategy) { 
    this.strategy = strategy; 
    } 

    public doSomething(rs) { 
    strategy.processResultSet(rs); 
} 

El problema es que no quiero pasar objeto estrategia de contexto, pero me gustaría crear algo li ke StrategyFactory que será responsable de la creación de la implementación de la Estrategia concreta. Separaría Cliente de Estrategia, ¿es un buen diseño?

¿Es una mezcla de Estrategia y Fábrica o, de hecho, solo Patrón de fábrica?

+0

Si separa al Cliente de su implementación de estrategia, ¿cómo va a saber su Factory (o posiblemente Abstract Factory) qué Strtegy implementar cuando intente instanciar el objeto? –

+0

La fábrica puede obtener esa información no del cliente, sino de otro lugar (configuración, por ejemplo). Sin conocer su implementación exacta, es imposible saberlo. –

+0

Ambos son puntos válidos @ Alcon, pero sería más fácil hacer una sugerencia informada si tuviéramos todos los detalles. –

Respuesta

8

Definitivamente es una combinación de estrategia y fábrica, pero no creo que sea malo. Los patrones están destinados a combinarse y usarse entre ellos.

Es difícil decir sin ver este plan de diseño en contexto, si este es un buen diseño o uno malo. Con solo la información que ha proporcionado aquí, podría ser de cualquier manera.

Parece que su cabeza está en el lugar correcto, pero permítanme darles una palabra de advertencia: no se estire demasiado para separar a su cliente de su estrategia. He hecho esto en el pasado y me ha llevado a un lío complicado que hubiera sido mucho más simple si hubiera permitido una pequeña conexión entre las dos partes de mi código. La separación es buena, pero luchar para mantener una separación perfecta puede llevar a un código incorrecto y todo tipo de problemas.

+0

Para ser más precisos. Tengo: 1) Clase de servicio 2) La clase de servicio contiene una referencia a la clase JDBCDAO. 3) La clase JDBCDAO contiene un método que hace: ResultSet rs = ps.executeQuery(); No deseo devolver rs al servicio, pero dejo que el objeto JDBCDAO lo procese y devuelva un objeto apropiado, así que quería crear esta fábrica (que crea la estrategia adecuada) como miembro de la clase JDBCDAO. –

0

En el escenario que representa, no sería realmente necesario un Contexto, que en su lugar sería reemplazado por la Fábrica que desee. El patrón de estrategia en este caso es solo una sobrecarga y una capa innecesaria de complejidad. Todo lo que necesita es una interfaz o clase abstracta, implementaciones y una Fábrica o Proxy para recuperar las implementaciones.

+2

Si usa una interfaz e implementaciones para representar los diferentes algoritmos de manejo, por definición eso es una Estrategia, ¿no es así? –

2

Hemos utilizado esto en muchos escenarios de análisis diferentes y ciertamente funciona. He escrito sobre esto con un ejemplo de código: http://www.herrodius.com/blog/136

El truco que utilizamos es dar a la interfaz de estrategia un método "canProcess" adicional que simplemente devuelve un valor booleano si la estrategia puede manejar los datos. La fábrica simplemente recorre todas sus estrategias y pregunta a cada una si puede funcionar con los datos. Si se puede, devolvemos esa estrategia o ejecutamos la estrategia.

0

Anny comentarios relacionados con mis pensamientos:

1) Hay un servicio - Singleton. 2) Contiene una referencia a la clase DAO; también es un singleton. 3) En DAO hay un método que recupera ResultSet: ResultSet rs = ps.executeQuery(); Me gustaría crear una estrategia apropiada dentro de DAO para procesar este conjunto de resultados. No puedo pasar esta estrategia en el constructor DAO porque es específico para la solicitud entrante. Pasarlo en el constructor lo haría igual para todas las solicitudes entrantes. Así que decidí crear una fábrica dentro de DAO (instancia de objeto DAO) y dentro de un método crearé una estrategia adecuada (basada en la solicitud - objeto local) de fábrica y la usaré para procesar el conjunto de resultados.

¿Es buena esta solución en su opinión?

+0

No, está sobrediseñado. Simplemente implemente la lógica en su clase DAO sin fábricas o estrategias. Si identifica cualquier código común o estándar mientras o después de implementar esto, redefine su código. Pero no dude en hacerlo funcionar con un simple 'si' primero. – eljenso

+0

Los Singletons son conocidos por hacer que el código sea difícil de probar. ¿Has considerado la capacidad de prueba? – TrueWill

0

Creo que el patrón de estrategia debe ir con un patrón de fábrica. Y de alguna manera lo usaste es absolutamente correcto. En segundo lugar, sería mejor si mantuviera la clase de contexto como una clase abstracta para que pueda ampliar contextos diferentes según su requisito. El resto de las cosas parece bueno, pero de acuerdo con el ejemplo que mencionaste, creo que no fue necesario, pero lo has usado de la manera correcta.

Cuestiones relacionadas