2008-09-26 16 views
6

¿Cuáles son (si los hay) los supuestos o restricciones implícitas y las diferencias de diseño como:Pregunta de patrón de estructura de clase. ¿Qué debería elegir?

a) Este:

class SampleClass1 
{ 
    IWorker workerA; 
    IWorker workerB; 

    void setWorkerA(IWorker w); 
    void setWorkerB(IWorker w); 
    WorkResult doWork(); 
} 

B) frente a esto:

class SampleClass2 
{ 
    WorkResult doWork(IWorker workerA, IWorker workerB); 
} 

Sé que depende del proyecto específico, pero ¿qué ocurre si la clase anterior es parte de un marco pequeño? La primera clase es capaz de mantener el estado y separar los pasos de forma más natural, pero la segunda clase asegura una "comunicación en tiempo real" con la persona que llama de forma más natural ya que Worker se pasa cada vez que se llama a doWork().

¿Hay algún uso recomendado o prácticas genéricas que guíen la elección entre las dos formas anteriores? Gracias.

Respuesta

5

En la opción (A) que está creando lo que se conoce como un objeto de función o Functor, este es un patrón de diseño que es well documented.

Las dos ventajas principales son:

  • Los trabajadores pueden ser establecidos por en un lugar y luego el objeto que se utiliza en otros lugares
  • El objeto puede conservar el estado de una llamada a

También si están utilizando un marco de inyección de dependencia (Spring, Guice, etc.). El functor se puede inicializar automáticamente e inyectar donde sea necesario.

Los objetos de función se utilizan ampliamente en bibliotecas, p. el C++ Standard Template Library

0

Otra opción:

clase

IWorker:

estática WorkResult DoWork (Iworker a, Iworker b);

1

Si más de un método depende de IWorker a y b IWorker, digo hacer la muestra A.

Si solamente DoWork() utiliza tanto IWorker a y b IWorker, y luego hacer la muestra B.

también , ¿cuál es el verdadero propósito de tu SampleClass? doWork se parece un poco más a un método de utilidad que cualquier otra cosa.

1

A) es un diseño incorrecto porque permite que el objeto sea defectuoso (es posible que no se haya establecido una o las dos clases de trabajadores).

B) puede ser bueno. Sin embargo, que sea estático, si no depende del estado interno de SampleClass2

+0

Creo que en este ejemplo básico, realmente no podemos llamar a A un mal diseño porque es solo un representante de una estructura de clase, no realmente la clase real. Además, doWork podría lanzar una excepción si no tiene una instancia de ambas clases, lo que podría ser aceptable. – scubabbl

+0

Entiendo la pregunta como una pregunta de diseño. Y las clases como A) son típicas en mi humilde opinión para las clases que crean muchos problemas cuando se usan en otras partes del código. Pueden ser transparentes para el diseñador de la clase original, pero son puntos típicos de falla cuando los usa otra persona. – Thorsten79

0

IMO 2nd approach se ve mejor, requiere que quien llama use menos código para realizar una tarea. El segundo enfoque es menos propenso a errores, el que llama no tiene que preocuparse de que el objeto no se haya inicializado por completo.

0

¿Qué tal vez la definición de un WorkDelegate (o, alternativamente, una interfaz que tiene un único método doWork sin argumentos) que simplemente devuelve un WorkResult y dejar que las clases individuales decidir cómo lo implementan? De esta forma, no te limites a decisiones prematuras.

6

SampleClass1

  • puedo necesitar para mantener el estado de los trabajadores entre DoWork
  • que podría necesitar la capacidad de fijar los trabajadores de forma individual. (doWork con 1 y 2, luego con 2 y 3)
  • Quiero mantener a los trabajadores porque se podría esperar ejecutar doWork varias veces en los mismos trabajadores.
  • No soy una clase de utilidad. Una instancia de mí es importante.

SampleClass2

  • Dame dos trabajadores y voy a hacer el trabajo con ellos.
  • No me importa quiénes son y no quiero mantenerlos.
  • Es el trabajo de otra persona mantener el emparejamiento entre los trabajadores.
  • Puedo ser más una clase de utilidad. Quizás puedo ser estático.
2

Otra opción, una variante del caso A, son los siguientes:

 
class SampleClass3 
{ 
    SampleClass3(IWorker workerA, IWorker workerB); 
    WorkResult doWork(); 
} 

Ventajas:

  • Es más difícil hacer que el objeto defectuoso, ya que se requiere para abastecer a todos los trabajadores que se necesitan en el momento de la construcción (en contraste con el caso A).

  • Todavía se puede llevar el estado dentro de SampleClass3 y/o uno de los trabajadores. (Esto es imposible en el caso B.)

Desventajas:

  • Tienes que tener todos sus trabajadores listos antes de construir SampleClass3, en lugar de ser capaz de proporcionarles más tarde. Por supuesto, también puede proporcionar a los incubadores, para que puedan cambiarse más tarde.
Cuestiones relacionadas