2012-05-03 9 views
5

Cho phép nói rằng tôi có một composite thiết lập như sau:Tôi nên tiếp cận bao bọc mẫu Composite vào mẫu Builder như thế nào?

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 
} 

Bây giờ, làm thế nào tôi sẽ đi về gói này composite thành một mô hình Builder, vì vậy mà tôi có thể đơn giản hóa mã khách hàng bằng cách cho phép nó không quan tâm (hoặc chăm sóc ít hơn) về sự phức tạp của cách liên kết trẻ với Composite của chúng tôi?

Trả lời

2

Dưới đây là ví dụ về người xây dựng làm cho một tổng hợp động vật của các bộ phận động vật khác nhau. Bạn sẽ có thể sửa đổi nó cho ứng dụng cụ thể của bạn.

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

Cám ơn một câu trả lời nhanh, nhưng bí quyết Animal composit ở đây? Có lẽ tôi nên thuật lại câu hỏi: Có cấu trúc tương tự [this] (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) Làm thế nào tôi sẽ quấn nó xung quanh với một mô hình xây dựng để mã khách hàng để tạo ra các yếu tố Composite sẽ đơn giản và/hoặc phù hợp hơn với một số hình thức kịch bản? –

+0

BodyPart là thành phần và Monkey là một hỗn hợp. Ví dụ này là bằng phẳng nhưng nếu bạn đã làm một cây, như ngón tay trên một bàn tay trên một cánh tay sau đó sẽ có lá. – eabraham

+0

Vâng, đó là những gì tôi đã có trong đầu của tôi trước khi hỏi và những gì cuối cùng làm cho tôi đặt câu hỏi. Trong khi điều này có hiệu quả, nó dường như chỉ làm phức tạp mã khách hàng (hoặc hạn chế tính linh hoạt của nó) và có câu hỏi liệu tôi có cần tạo thành phần của các nhà xây dựng để làm cho toàn bộ linh hoạt không, ví dụ như một người xây dựng các bộ phận cơ thể nhỏ hơn, người xây dựng để tạo chân, và sau đó một người xây dựng sẽ dựa vào những người xây dựng cấp thấp hơn để làm cho toàn bộ động vật? Vì vậy, tôi nghĩ rằng điều này sẽ chỉ gây ra một sự bùng nổ của các lớp học để giữ cho toàn bộ điều hơi linh hoạt. –

0

Trong trình tạo, thêm phương thức "startComposite" và "endComposite". Những phương pháp này đẩy một hỗn hợp vào một ngăn xếp và loại bỏ một hỗn hợp từ ngăn xếp. Thư để thêm phần tử luôn thêm vào đầu ngăn xếp.

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

Nếu phương pháp xây dựng của bạn luôn luôn trả về xây dựng, bạn có thể loại bỏ sự lặp lại của người nhận:

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

Hmm, đây có thể là những gì tôi đang tìm kiếm. Tôi sẽ cố gắng làm việc trong ngày để xem nó như thế nào. Cảm ơn vì đã dành thời gian cho tôi. –