设计模式(九)建造者模式
建造者模式(Builder),又叫生成器模式,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式可以将一个产品的内部表象与产品的生成过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象。如果我们用了建造者模式,那么用户就只需指定需要建造的类型就可以得到它们,而具体建造的过程和细节就不需知道了。
基本代码
1 // 产品类 2 class Product 3 { 4 IList<string> parts = new List<string>(); 5 // 添加产品部件 6 public void Add(string part) 7 { 8 parts.Add(part); 9 } 10 11 public void Show() 12 { 13 Console.WriteLine("\n 产品 创建 ----"); 14 // 列举所有的产品部件 15 foreach(string part in parts) 16 { 17 Console.WriteLine(part); 18 } 19 } 20 } 21 // 抽象建造者类 22 abstract class Builder 23 { 24 public abstract void BuildPartA(); 25 public abstract void BuildPartB(); 26 public abstract Product GetResult(); 27 } 28 // 具体建造者类 29 class ConcreteBuilder1 : Builder 30 { 31 private Product product = new Product(); 32 33 public override void BuildPartA() 34 { 35 product.Add(" 部件A "); 36 } 37 38 public override void BuildPartB() 39 { 40 product.Add(" 部件B "); 41 } 42 43 public override Product GetResult() 44 { 45 return product; 46 } 47 } 48 // 49 class ConcreteBuilder2 : Builder 50 { 51 private Product product = new Product(); 52 53 public override void BuildPartA() 54 { 55 product.Add(" 部件X "); 56 } 57 58 public override void BuildPartB() 59 { 60 product.Add(" 部件Y "); 61 } 62 63 public override Product GetResult() 64 { 65 return product; 66 } 67 } 68 // 指挥者类 69 class Director 70 { 71 public void Construct(Builder builder) 72 { 73 builder.BuildPartA(); 74 builder.BuildPartB(); 75 } 76 } 77 78 // 客户端 79 static void Main(string[] args) 80 { 81 Director director = new Director(); 82 Builder b1 = new ConcreteBuilder1(); 83 Builder b2 = new ConcreteBuilder2(); 84 85 director.Construct(b1); 86 Product p1 = b1.GetResult(); 87 p1.Show(); 88 89 director.Construct(b2); 90 Product p2 = b2.GetResult(); 91 p2.Show(); 92 93 Console.Read(); 94 }
建造者模式是在当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时适用的模式。
【例】建造卡通人
建造者模式的好处是使得建造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了。
代码实现
1 abstract class PersonBuilder 2 { 3 protected Graphics g; 4 protected Pen p; 5 6 public PersonBuilder(Graphics g, Pen p) 7 { 8 this.g = g; 9 this.p = p; 10 } 11 12 public abstract void BuildHead(); 13 public abstract void BuildBody(); 14 public abstract void BuildArmLeft(); 15 public abstract void BuildArmRight(); 16 public abstract void BuildLegLeft(); 17 public abstract void BuildLegRight(); 18 } 19 20 class PersonThinBuilder : PersonBuilder 21 { 22 public PersonThinBuilder(Graphics g, Pen p) : base( g, p ) 23 { 24 } 25 public override void BuildHead() 26 { 27 g.DrawEllipse(p, 50, 20, 30, 30); 28 } 29 public override void BuildBody() 30 { 31 g.DrawRectangle(p, 60, 50, 10, 50); 32 } 33 public override void BuildArmLeft() 34 { 35 g.DrawLine(p, 60, 50, 40, 100); 36 } 37 public override void BuildArmRight() 38 { 39 g.DrawLine(p, 70, 50, 90, 100); 40 } 41 public override void BuildLegLeft() 42 { 43 g.DrawLine(p, 60, 100, 45, 150); 44 } 45 public override void BuildLegRight() 46 { 47 g.DrawLine(p, 70, 100, 85, 150); 48 } 49 } 50 51 // 指挥者,用来控制建造过程,也用来隔离用户与建造过程的关联 52 class PersonDirector 53 { 54 private PersonBuilder pb; 55 public PersonDirector(PersonBuilder pb) 56 { 57 this.pb = pb; 58 } 59 60 public void CreatePerson() 61 { 62 pb.BuildHead(); 63 pb.BuildBody(); 64 pb.BuildArmLeft(); 65 pb.BuildArmRight(); 66 pb.BuildLegLeft(); 67 pb.BuildLegRight(); 68 } 69 } 70 71 // 客户端 72 static void Main(string[] args) 73 { 74 Pen p = new Pen(Color.Yellow); 75 76 PersonThinBuilder ptb = new PersonThinBuilder(pictureBox1.CreateGraphics(), p); 77 PersonDirector pdThin = new PersonDirector(ptb); 78 pdThin.CreatePerson(); 79 }