2010-03-31 14 views
7

que estoy tratando de aplicar el patrón decorador diseño a la siguiente situación:aplicar el patrón decorador a las formas

tengo 3 clases diferentes de formas: verde, amarillo, rojo.

Ahora, cada una de esas formas puede tener un conjunto diferente de atributos. Pueden tener un cuadro de minimización deshabilitado, un cuadro maximizado deshabilitado y pueden estar siempre en la parte superior.

Me trataron de modelar esta de la siguiente manera:

   Form <---------------------------------------FormDecorator 
       /\             /\ 
    |---------|-----------|    |----------------------|-----------------| 
GreenForm YellowForm RedForm MinimizeButtonDisabled MaximizedButtonDisabled AlwaysOnTop 

Aquí está mi código GreenForm:

public class GreenForm : Form { 
    public GreenForm() { 
     this.BackColor = Color.GreenYellow; 
    } 

    public override sealed Color BackColor { 
     get { return base.BackColor; } 
     set { base.BackColor = value; } 
    } 
} 

FormDecorator:

public abstract class FormDecorator : Form { 
    private Form _decoratorForm; 

    protected FormDecorator(Form decoratorForm) { 
     this._decoratorForm = decoratorForm; 
    } 
} 

y finalmente NoMaximizeDecorator:

public class NoMaximizeDecorator : FormDecorator 
{ 
    public NoMaximizeDecorator(Form decoratorForm) : base(decoratorForm) { 
     this.MaximizeBox = false; 
    } 
} 

Así que aquí es el código que se ejecuta:

static void Main() 
{ 
    Application.EnableVisualStyles(); 
    Application.SetCompatibleTextRenderingDefault(false); 
    Application.Run(CreateForm()); 
} 

static Form CreateForm() { 
    Form form = new GreenForm(); 
    form = new NoMaximizeDecorator(form); 
    form = new NoMinimizeDecorator(form); 

    return form; 
} 

El problema es que tengo una forma que no es verde y todavía que me permite maximizarla. Solo toma en consideración el formulario NoMinimizeDecorator. Comprendo por qué sucede esto, pero estoy teniendo problemas para entender cómo hacer que esto funcione con este patrón.

Sé que hay mejores formas de lograr lo que quiero. Hice este ejemplo como un intento de aplicar el Patrón Decorador a algo. Quizás este no fue el mejor patrón que podría haber usado (si es que lo hubiera hecho) para este tipo de escenario. ¿Hay algún otro patrón más adecuado que el Decorador para lograr esto? ¿Estoy haciendo algo mal cuando trato de implementar el Patrón Decorador?

Gracias

Respuesta

6

El problema aquí es que usted' No estamos implementando el patrón de decorador. Para una implementación adecuada del patrón, debe crear la subclase Form para crear su decorador, y luego interceptar todas las operaciones realizadas en su decorador y reenviarlas a su instancia privada Form. De alguna manera haces eso, excepto que aparte de asignar una referencia en el constructor FormDecorator, nunca más usas esa instancia privada de Form. El resultado neto es que creas un GreenForm, luego lo envuelves en un NoMaximizeDecorator, y luego lo envuelves en un NoMinimizeDecorator. Pero debido a que nunca reenvía las operaciones tomadas contra el NoMinimizeDecorator a la instancia envuelta Form, solo la instancia NoMinimizeDecorator realmente aplica cualquier comportamiento a la instancia que se usa. Esto concuerda con lo que observa cuando ejecuta su código: una ventana estándar con un botón Minimizar desactivado.

Form es un muy mal ejemplo para la creación de decoradores en C#, porque la mayoría de sus propiedades y métodos son no virtual, es decir, si se está accediendo a la forma decorada a través de una referencia Form, que no hay manera de interceptar la base propiedades de la clase: no puede "envolver" efectivamente Form.

EDITAR

Se me ocurre que la declaración "La forma es un muy mal ejemplo para la creación de decoradores en C#" en realidad plantea la cuestión de qué es un buen ejemplo. Normalmente, utilizará el patrón de decorador para proporcionar una implementación de interfaz personalizada sin implementar la implementación completa desde cero. Un ejemplo común de muy son colecciones genéricas. La mayoría de todo lo que quiere funcionalidad de la lista no depende, por ejemplo, List<String>, sino más bien en IList<String>. Por lo tanto, si, por ejemplo, quiere una colección personalizada que no acepte cadenas de menos de 5 caracteres, usaría algo como lo siguiente:

2

Esta es una aplicación incorrecta de la pauta decorador. El patrón de decorador está relacionado con el comportamiento de los objetos. Usted está construyendo objetos que cae bajo el paraguas creacional. Si bien puede ser capaz de entender que "no tener un botón de maximizar" es un comportamiento que suena un poco fuera de control.

No creo que haya una forma real de arreglar su diseño. El patrón de decorador simplemente no encaja. Cualquier intento de arreglar esto va a ser increíblemente complicado cuando podrías usar un generador.

Lo que podía ver haciendo es decorar el constructor de un formulario para realizar estas acciones mientras que la construcción. Se vería algo como esto ...

public interface IFormBuilder { 
    public Form BuildForm(); 
} 

public class FormBuilder : IFormBuilder { 
    public Form BuildForm(){ 
     return new Form(); 
    } 
} 

public class NoMaximizeFormBuilder : IFormBuilder { 
    private IFormBuilder _builder; 
    public NoMaximizeFormBuilder (IFormBuilder builder){ 
     _builder = builder;    
    } 
    public Form BuildForm(){ 
     f = _builder.BuildForm(); 
     f.MaximizeBox = false; 
     return f; 
    } 
} 

y se podía utilizar de esta manera ...

static void Main() 
{ 
    Application.EnableVisualStyles(); 
    Application.SetCompatibleTextRenderingDefault(false); 
    Application.Run(CreateForm()); 
} 

static Form CreateForm() { 

    var b = new FormBuilder(); 
    var b = new NoMaximizeFormBuilder(b); 
    return b.Build(); 
} 

Pero incluso eso es un poco feo. Es posible que pueda transformar esto en una interfaz fluida para crear formularios.

+0

+1. Es "un poco feo", pero creo que tiene potencial. –

0

tratar de hacer que su patrón para aplicar las propiedades del decorador con el mismo objeto, no creando nuevas formas:

public abstract class FormDecorator { 
    protected Form _decoratorForm; 

    protected FormDecorator(Form decoratorForm) { 
     this._decoratorForm = decoratorForm; 
    } 
    public abstract void Decorate(); 
} 

public class NoMaximizeDecorator : FormDecorator 
{ 
    public NoMaximizeDecorator(Form decoratorForm) : base(decoratorForm) { 
     Decorate(); 
    } 
    public override void Decorate() { 
     _decoratorForm.MaximizeBox = false; 
    } 
} 

Y en su principal:

static Form CreateForm() { 
    Form form = new GreenForm(); 
    new NoMaximizeDecorator(form); 
    new NoMinimizeDecorator(form); 

    return form; 
} 
+1

El patrón de decorador no se ve así. La jerarquía de clase decoradora debe heredar la clase base de la jerarquía de clase decorada. Se supone que el FormDecorator abstracto define un comportamiento predeterminado para todos los métodos de clase base. – Seb

+1

Sí, no se ve así. Sin embargo, hace lo que se supone. –

Cuestiones relacionadas