我该如何处理将Composite模式包装到Builder模式中?

时间:2012-05-03 18:18:20

标签: java oop design-patterns composite builder-pattern

假设我的复合设置如下:

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
}

现在,我将如何将 Composite 包装到 Builder 模式中,这样我就可以通过使客户端代码无需关心(或者更少关心)来简化客户端代码)关于如何将儿童与复合

联系起来的复杂性

2 个答案:

答案 0 :(得分:2)

以下是制作不同动物部位的动物复合物的建造者的示例。您应该能够针对特定应用修改它。

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;
        }
    }
}

答案 1 :(得分:0)

在构建器中,添加方法“startComposite”和“endComposite”。这些方法将复合材料推入堆栈并从堆栈中移除复合材料。添加元素的消息总是添加到堆栈顶部。

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

如果构建器方法始终返回构建器,则可以消除接收器的重复:

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