2012-05-03 16 views
5

que permite decir que tengo una Compuesto establecido de la siguiente manera:¿Cómo debo enfocar el patrón Compuesto en el patrón de Constructor?

public abstract class Element { 
    //position, size, etc. 

    //element methods 

    //setters/getters 
} 

public class SimpleElement1 extends Element { 
    //... 
} 

public class SimpleElement2 extends Element { 
    //... 
} 

public class CompositeElement extends Element { 
    protected List<Element> childrenElements; 

    //methods to add/remove/get children 
} 

Ahora, ¿cómo hago para envolver este Compuesto aparecer como un patrón Constructor, de modo que pueda simplificar el código de cliente al permitir que no le importe (o le importe menos) las complejidades de cómo vincular a los niños a su compuesto?

Respuesta

2

Aquí es un ejemplo de un constructor de hacer un material compuesto de los animales de diferentes partes de animales. Debería poder modificarlo para su aplicación particular.

class BuilderDesignPattern{ 
    public static void Main(string[] args) 
     { 
      Kid aKid = new Kid(); 
      aKid.Name = "Elizabeth"; 

      AnimalBuilder builderA = new MonkeyBuilder(); 
      aKid.MakeAnimal(builderA); 
      builderA.aAnimal.ShowMe(); 

      AnimalBuilder builderB = new KittenBuilder(); 
      aKid.MakeAnimal(builderB); 
      builderB.aAnimal.ShowMe(); 

     } 
    } 
    public abstract class AnimalBuilder 
    { 
     public Animal aAnimal; 

     public abstract void BuildAnimalHeader(); 
     public abstract void BuildAnimalBody(); 
     public abstract void BuildAnimalLeg(); 
     public abstract void BuildAnimalArm(); 
     public abstract void BuildAnimalTail(); 
    } 
    public class MonkeyBuilder : AnimalBuilder 
    { 

     public MonkeyBuilder() 
     { 
      aAnimal = new Monkey(); 
     } 

     public override void BuildAnimalHeader() 
     { 
      aAnimal.Head = "Moneky's Head has been built"; 
     } 

     public override void BuildAnimalBody() 
     { 
      aAnimal.Body = "Moneky's Body has been built"; 
     } 

     public override void BuildAnimalLeg() 
     { 
      aAnimal.Leg = "Moneky's Leg has been built"; 
     } 

     public override void BuildAnimalArm() 
     { 
      aAnimal.Arm = "Moneky's Arm has been built"; 
     } 

     public override void BuildAnimalTail() 
     { 
      aAnimal.Tail = "Moneky's Tail has been built"; 
     } 
    } 
    public class KittenBuilder : AnimalBuilder 
    { 
     public KittenBuilder() 
     { 
      aAnimal = new Kitten(); 
     } 

     public override void BuildAnimalHeader() 
     { 
      aAnimal.Head = "Kitten's Head has been built"; 
     } 

     public override void BuildAnimalBody() 
     { 
      aAnimal.Body = "Kitten's Body has been built"; 
     } 

     public override void BuildAnimalLeg() 
     { 
      aAnimal.Leg = "Kitten's Leg has been built"; 
     } 

     public override void BuildAnimalArm() 
     { 
      aAnimal.Arm = "Kitten's Arm has been built"; 
     } 

     public override void BuildAnimalTail() 
     { 
      aAnimal.Tail = "Kitten's Tail has been built"; 
     } 
    } 
    public abstract class Animal 
    { 
     public BodyPart Head { get; set; } 
     public BodyPart Body { get; set; } 
     public BodyPart Leg { get; set; } 
     public BodyPart Arm { get; set; } 
     public BodyPart Tail { get; set; } 


     //helper method for demo the Polymorphism, so we can 
     //easily tell what type object it is from client. 
     public abstract void Eat(); 

     //helper method for demo the result from client 
     public void ShowMe() 
     { 
      Console.WriteLine(Head); 
      Console.WriteLine(Body); 
      Console.WriteLine(Leg); 
      Console.WriteLine(Arm); 
      Console.WriteLine(Tail); 
      Eat(); 

     } 
    } 
    public class Monkey : Animal 
    { 
     //helper method to show monkey's property for demo purpose 
     public override void Eat() 
     { 
      Console.WriteLine("Since I am Monkey, I like to eat banana"); 
     } 
    } 
    public class Kitten : Animal 
    { 
     public override void Eat() 
     { 
      Console.WriteLine("Since I am Kitten, I like to eat kitten food"); 
     } 
    } 
    public class Kid 
    { 
     public string Name { get; set; } 

     //construct process to build an animal object, 
     //after this process completed, a object 
     //will be consider as a ready to use object. 
     public void MakeAnimal(AnimalBuilder aAnimalBuilder) 
     { 
      aAnimalBuilder.BuildAnimalHeader(); 
      aAnimalBuilder.BuildAnimalBody(); 
      aAnimalBuilder.BuildAnimalLeg(); 
      aAnimalBuilder.BuildAnimalArm(); 
      aAnimalBuilder.BuildAnimalTail(); 
     } 


    } 
    public class BodyPart{ 
     String name= ""; 
     public BodyPart(String name){ 
      this.name=name; 
     } 
    } 
} 
+0

Gracias por una respuesta rápida, pero cómos compuesta Animal en esta lista? Tal vez debería reformular una pregunta: Tener una estructura similar a [esta] (http://upload.wikimedia.org/wikipedia/commons/thumb/5/5a/Composite_UML_class_diagram_%28fixed%29.svg/800px-Composite_UML_class_diagram_%28fixed% 29.svg.png) ¿cómo podría envolverlo con un patrón de generador para que el código del cliente para crear elementos compuestos sea más simple y/o más adecuado para algún tipo de scripting? –

+0

BodyPart es el componente y Monkey es un compuesto. Este ejemplo es plano, pero si hicieras un árbol, como un dedo en una mano en un brazo, entonces habría hojas. – eabraham

+0

Bueno, eso es lo que tenía en mi cabeza antes de preguntar y lo que finalmente me hizo hacer la pregunta. Si bien esto funcionaría, parece que solo está complicando el código del cliente (o limitando su flexibilidad) y existe la pregunta de si necesitaría hacer la composición de los constructores para que todo sea flexible, por ejemplo, un constructor para hacer un brazo de partes del cuerpo más pequeñas, constructor para hacer una pierna, y luego un constructor que dependerá de esos constructores de nivel inferior para hacer animales completos? Entonces creo que esto solo causaría una explosión de clases para mantener todo flexible. –

0

En su constructor, agregue los métodos "startComposite" y "endComposite". Estos métodos empujan un compuesto en una pila y eliminan un compuesto de la pila. Los mensajes para agregar elementos siempre se agregan a la parte superior de la pila.

builder.startComposite(); 
     builder.simpleElement1(); 
     builder.simpleElement2(); 
    builder.endComposite(); 
    builder.startComposite(); 
     builder.simpleElement2(); 
    builder.endComposite(); 

Si sus métodos constructor siempre devuelven el constructor, puede eliminar la repetición del receptor:

builder. 
     startComposite(). 
      simpleElement1(). 
      simpleElement2(). 
     endComposite(). 
     startComposite(). 
      simpleElement2(). 
     endComposite(); 
+0

Hmm, esto podría ser lo que estoy buscando. Trataré de resolverlo durante el día para ver cómo resulta. Gracias por tu tiempo. –

Cuestiones relacionadas