2011-05-27 18 views
5

Después de implementar el patrón de decorador y codificar un par de decoradores, noté que el API permite a un usuario apilar decoradores incompatibles. ¿Es esta una restricción natural del patrón con el que el diseñador de API debería vivir, o una implementación errónea del patrón por mi parte?Decorar un decorador

Por ejemplo, imagine que hay una clase que puede estar decorada con un decorador binario que codifica datos en binario, o un decorador de cadenas que codifica datos en una cadena. Dado que se utilizó el decorador de cuerdas, puede decorarse con un decorador JSON o XML. Ahora es evidente que después de haber aplicado el decorador JSON sería incompatible usar el decorador XML encima de él, o si el decorador binario se usó, el decorador XML/JSON no sirve de nada.

ejemplo de Java mediante el paquete java.io:

InputStream is = someInputStream; 
BufferedInputStream bis = new BufferedInputStream(is); 
ObjectInputStream ois = new ObjectInputStream(bis); 
DataInputStream dis = new DataInputStream(ois); 

El resultado de esto es indefinida, pero la API permite.

+1

¿Por qué no se puede codificar la clase en cualquier formato disponible según el argumento pasado al método de codificación o en la invocación de método por separado? ¿Por qué la decoración de una clase con el decorador JSON lo hace incompatible con el decorador XML? – Eimantas

+0

Buen punto. Podría, pero en mi caso sería una sobrecarga de programación. – yannisf

Respuesta

1

Los decoradores hacen que la funcionalidad sea fácil de combinar. Si la funcionalidad combinada tiene sentido depende del usuario de la API.

0

Este tipo de aplicación de restricciones no es parte del patrón de decorador como lo conozco, pero no hay ninguna razón por la que no se pudo hacer. Es una compensación entre la simplicidad de la API y la seguridad (de los errores del programador).

1

Las clases de IO de Java parecen ser un caso de violación de uno o más principios de diseño de OO, como Interface Segregation Principle y Liskov Substitution Principle, y el abuso de la herencia de implementación. Si ObjectInputStream y DataInputStream no heredarán de InputStream, entonces solo podrían tener aquellos métodos que se les permita usar en ellos. La reutilización del código a través de la herencia de implementación es probablemente lo que ha causado este problema; podría haberse evitado al favorecer la composición por sobre la herencia.

+0

¡Muy buenos análisis, puntos y enlaces! – yannisf

Cuestiones relacionadas