2010-05-08 24 views
5

Esto es más una cuestión de diseño ... No se puede decorar un patrón de diseño si:¿Cómo se implementa el patrón Decorator si no se puede heredar de la clase que se desea decorar?

1) El objeto está marcado como "sellado" lo que significa que no puede extenderse. 2) o si desea sobrescribir un método, pero no es virtual.

¿Qué puedes hacer entonces? Se considera que no puede cambiar el código fuente de la clase si no tiene el código fuente (como una biblioteca de terceros).

Respuesta

1

Puede crear su propia clase que envuelva la clase de terceros y decorar esa clase. Tu clase usará la implementación de clase envolvente. La clase contenedora actúa como un Adaptador.

+1

Pero no podrá sustituir la clase de sujeto con la clase de proxy porque tienen diferentes tipos. – Ikke

+0

@ikke: Eso es verdad. Por lo tanto, no dije el patrón proxy. – Ikaso

+1

¿no sería eso un adaptador en lugar de un proxy? –

2

Muchos de los enfoques que se pueden tomar en función de la cantidad de control sobre el código que realmente tiene:

1) ¿Está eliminando una instancia de una clase cerrada al código de terceros? Si es así, no hay mucho que pueda hacer, excepto rezar para que su tercero acepte una interfaz en lugar de un objeto concreto.

Es totalmente posible escribir ganchos en el CLR para interceptar los métodos en su clase sellada, que es cómo funcionan algunos marcos de burla para burlarse de los métodos no virtuales y las clases selladas. I no lo haga recomendar esto porque su código de terceros se escribió contra una implementación particular de un objeto, y cambiar la implementación bajo la nariz del código de terceros podría tener consecuencias no triviales e indefinidas.

2) ¿Está consumiendo la clase sellada en su propio código? Si es así, ¡ve a ir a la envoltura del gadget! Cree una clase no sellada con los mismos métodos públicos que su clase sellada, los métodos públicos deben pasar a su objeto sellado, luego puede anular la funcionalidad de su clase según sea necesario.

3) ¿Es el propietario del código de la clase sellada? Si es así, encuentre la definición de clase, haga doble clic en la palabra clave 'sellada' para resaltarla, presione la tecla Eliminar según sea necesario;) O tal vez cambie los métodos que aceptan su objeto sellado por una interfaz con los mismos métodos públicos.

5

La herencia no es necesaria para un patrón Decorator. El caso más simple es si el objeto que desea decorar implementa una interfaz. Entonces su decorador puede simplemente aplicar la misma interfaz:

[ IWindow ] 
[ + Draw() ] 
--------------- 
    | 
    +--- [ Window ] 
    | [ + Draw() ] 
    | 
    | 
    +--- [ DecoratedWindow ] 
     [ + Draw()  ] 
     ------------------- 
     | 
     +--- [ BorderDecorator ] 
     | 
     +--- [ VerticalScrollbarDecorator ] 
     | 
     +--- [ HorizontalScrollbarDecorator ] 

Ahora sólo puede hacer:

IWindow w = new BorderDecorator(
      new HorizontalScrollBarDecorator(
       new VerticalScrollBarDecorator(
       new Window(80, 24)))); 

// This is a window with a border and scrollbars, even though 
// the original Window class has no idea what those are. 
w.Draw(); 

Los detalles de lo que son posibles dependerá de la naturaleza exacta de la clase que está tratando de Decorar.

+0

+1 para diseñar contra interfaces. ¡Esto es * especialmente * importante si las clases no son heredables! – Aaronaught

0

Si no puede heredar y la clase original no implementa ninguna interfaz que también pueda implementar en su decorador, entonces creo que debería probar una clase proxy o un adaptador. Y si eso tampoco es posible, bueno, siempre tiene un "recurso técnico alternativo": podría definir un conversion operator que le permita convertir su decorador al original (aunque creo que esta no es una muy buena opción).

Cuestiones relacionadas