2010-04-06 23 views

Respuesta

9

Una mezcla es apta cuando agrega algún comportamiento a su clase. p.ej. la capacidad de enumerar en caso de un tipo de colección. Puede mezclar tantos conjuntos de comportamientos en su clase como desee. Es una buena forma de reutilizar el código común; básicamente obtienes muchos métodos gratis.

Un decorador por el contrario es más un interceptor furtivo. Expone la misma interfaz pública que el objeto de destino, contiene un objeto de destino al que delega todas las llamadas de los clientes; sin embargo, decora la llamada con algún procesamiento previo y/o posterior. p.ej. si estoy escribiendo código contra MyCollection y quiero que se registren todas las llamadas a este tipo. Podría derivar un nuevo decorador MyCollectionWithTimeStampedLogging ambos derivados de una base de ICollection para que se vean idénticos al cliente. El decorador tomaría una instancia de ICollection como un param del ctor y delegaría llamadas a él. p.ej. Agregar se vería así

public void Add(int item) 
{ 
    _logger.log(String.Format("{0} Add called with param {1}", DateTime.Now, item.ToString()); 
    _collection.Add(item); 
    _logger.log(String.Format("{0} Add completed with param {1}", DateTime.Now, item.ToString()); 
} 
+0

¿Entonces un decorador está un poco más cerca de lo que hace la Programación Orientada a Aspectos (AOP), y un mixin simplemente modifica sus clases existentes? – leeand00

+0

@ leeand00 - tipo de; AOP es mucho más que simples decoradores, creo. Los mixins son más frecuentes en los lenguajes dinámicos, con un mixin, puedes mezclar un montón de métodos en la definición de tu clase. p.ej. puede escribir implementaciones Cargar y Guardar (que reflejan en una clase y leer/escribir propiedades públicas en el disco) en un Módulo Persistente, luego mezclar esto en múltiples clases. Todas estas clases ahora pueden persistir en el disco. – Gishu

+0

Con AOP (con el que estoy más familiarizado que ... say mixins) puede especificar 3 cosas diferentes que pueden suceder con las interfaces seleccionadas. Puede especificar una acción previa, una acción posterior y, en su lugar, una acción. – leeand00

2

No estoy seguro de estar de acuerdo con la afirmación de que Decorator se extiende durante el tiempo de ejecución. Sé que eso es lo que dice Wikipedia, pero no creo que sea exacto. Sugiero leer la definición del GoF del patrón Decorator. Es una extensión dinámica, sí, pero ciertamente no tiene que ser en tiempo de ejecución.

+2

No tiene que ser así, pero puede ser. – leeand00

12

Al utilizar el patrón de decorador, por lo general encapsula, en lugar de extender (o mezclar) la clase base. A menudo lo hace porque quiere usar la funcionalidad de la clase pero desea envolver las llamadas para que pueda hacer algunos pasos adicionales antes o después de la llamada. Considere un LoggerDecorator

public class LoggerDecorator implements SomeInterface { 
     private SomeInterface delegate; 
     public void someMethod() { 
      LOGGER.debug("someMethod called"); 
      delegate.someMethod(); 
     } 
} 

Usted no quiere exponer en realidad el delegado, pero que desea utilizar su funcionalidad. Entonces, si usted nos mezcla o no, extiende una clase o decora realmente depende de lo que está tratando de hacer. ¿Estás ampliando una clase y agregándole nuevas funcionalidades? ¿O estás envolviendo/decorando la clase?

+0

@Jeff Por favor, vea lo que he comentado en la publicación de Gishu a continuación y dígame si lo tengo o no. – leeand00

+0

Creo que está en el camino correcto, pero AOP es un marco de interceptor dinámico, que se produce en tiempo de ejecución (o tiempo de compilación si compila con aspectj). En general, recomendaría ir a la ruta de decorador a menos que necesites AOP porque la inyección de tiempo de ejecución puede ser mucho más frágil si no tienes cuidado. –

Cuestiones relacionadas