¿Cómo debo acercarme a envolver el patrón Composite en el patrón Builder?

Digamos que tengo un Compuesto configurar de la siguiente manera:

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 haría para envolver esto? Compuesto subir a un Albañil patrón, de modo que pueda simplificar el código del cliente al permitir que no se preocupe (o se preocupe menos) por las complejidades de cómo vincular a los niños con su Compuesto?

preguntado el 03 de mayo de 12 a las 19:05

2 Respuestas

En su constructor, agregue los métodos "startComposite" y "endComposite". Estos métodos empujan un compuesto a 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 constructores siempre devuelven el constructor, puede eliminar la repetición del receptor:

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

contestado el 04 de mayo de 12 a las 00:05

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

Aquí hay un ejemplo de un constructor que hace un animal compuesto 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;
        }
    }
}

contestado el 03 de mayo de 12 a las 22:05

Gracias por una respuesta rápida, pero ¿cómo está Animal composite aquí? Tal vez debería reformular una pregunta: tener una estructura similar a este ¿Cómo lo envolvería con un patrón de construcción para que el código del cliente para crear elementos compuestos sea más simple y/o más adecuado para alguna forma de secuencias de comandos? - Nebojsa

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, habría hojas. - ebraham

Bueno, eso es lo que tenía en la cabeza antes de preguntar y lo que finalmente me hizo hacer la pregunta. Si bien esto funcionaría, parece que solo complica el código del cliente (o limita su flexibilidad) y existe la pregunta de si necesitaría hacer una composición de constructores para que todo sea flexible, por ejemplo, un constructor para hacer un brazo. partes del cuerpo más pequeñas, constructor para hacer una pierna, y luego un constructor que se basará en esos constructores de nivel inferior para hacer el animal completo? Así que creo que esto solo causaría una explosión de clases para mantener todo algo flexible. - Nebojsa

Un constructor aumenta su número de clases pero simplifica la creación de clases complejas. - ebraham

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.