【设计模式】好菜每回味不同 --- 建造者模式
一,概述
Builder模式的定义是:将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。 首先它意图是要构建一个复杂的对像,而这个复杂的对像往往需要由好几个子对像或分步骤来完成最终的这个对象的构建,而这个复杂对象的子对像经常需要不断的变化,但它的构建过程是相对是稳定的。
精髓:通过一个统一的工序或者约束构造出同一的对象。
二,引例
1)构造一个小人,需要有脚、手、身体、头
缺点:这样构造的小人,容易忘记构造手,脚之类的。
void button1_Click(object sender, EventArgs e)
{
Pen p = new Pen(Color.Yellow);
Graphics gThin = pictureBox1.CreateGraphics();
gThin.DrawEllipse(p, 50, 20, 30, 30);//头
gThin.DrawRectangle(p, 60, 50, 10, 50);//身体
gThin.DrawLine(p, 60, 50, 40, 100); //左手
gThin.DrawLine(p, 70, 50, 90, 100); //右手
gThin.DrawLine(p, 60, 100, 45, 150);//左脚
gThin.DrawLine(p, 70, 100, 85, 150);//右脚
Graphics gFat = pictureBox2.CreateGraphics();
gFat.DrawEllipse(p, 50, 20, 30, 30);
gFat.DrawEllipse(p, 45, 50, 40, 50);//胖子
gFat.DrawLine(p, 50, 50, 30, 100);
gFat.DrawLine(p, 80, 50, 100, 100);
gFat.DrawLine(p, 60, 100, 45, 150);
gFat.DrawLine(p, 70, 100, 85, 150);
}
2)构造小人二
改进之处:为了避免每次构建小人,有可能出错,所以将构建小人的方法写入一个类,每次构造时候,调用构造方法。
缺点:如果再构造一个高个子类,忘记画腿或者胳膊怎么办?
解决办法:构建一个人的基本类,把要实现的方法都写成纯虚函数。这样避免缺少某一部分了
private class PersonThinBuilder //瘦子类
{
public void Build()
{
g.DrawEllipse(p, 50, 20, 30, 30);
g.DrawRectangle(p, 60, 50, 10, 50);
g.DrawLine(p, 60, 50, 40, 100);
g.DrawLine(p, 70, 50, 90, 100);
g.DrawLine(p, 60, 100, 45, 150);
g.DrawLine(p, 70, 100, 85, 150);
}
}
class PersonFatBuilder //胖子类
{
public void Build()
{
g.DrawEllipse(p, 50, 20, 30, 30);
g.DrawEllipse(p, 45, 50, 40, 50);
g.DrawLine(p, 50, 50, 30, 100);
g.DrawLine(p, 80, 50, 100, 100);
g.DrawLine(p, 60, 100, 45, 150);
g.DrawLine(p, 70, 100, 85, 150);
}
}
3)建造者模式
说明:如果有的小人需要画的更细,则只需要在特定小人里面添加相应的函数即可。只有在每个类都需要创建的时候才需要写到抽象类中。
namespace 建造者模式 { abstract class PersonBuilder//抽象类 { protected Graphics g; protected Pen p; public PersonBuilder(Graphics g, Pen p) { this.g = g; this.p = p; } //如果是C++的话就要写成纯虚函数的形式 public abstract void BuildHead(); public abstract void BuildBody(); public abstract void BuildArmLeft(); public abstract void BuildArmRight(); public abstract void BuildLegLeft(); public abstract void BuildLegRight(); } class PersonThinBuilder : PersonBuilder //集成抽象类,必须实现抽象类中的每一个函数 { public PersonThinBuilder(Graphics g, Pen p) : base(g, p) { } public override void BuildHead() { g.DrawEllipse(p, 50, 20, 30, 30); } public override void BuildBody() { g.DrawRectangle(p, 60, 50, 10, 50); } public override void BuildArmLeft() { g.DrawLine(p, 60, 50, 40, 100); } public override void BuildArmRight() { g.DrawLine(p, 70, 50, 90, 100); } public override void BuildLegLeft() { g.DrawLine(p, 60, 100, 45, 150); } public override void BuildLegRight() { g.DrawLine(p, 70, 100, 85, 150); } } class PersonFatBuilder : PersonBuilder //旁人类似 { public PersonFatBuilder(Graphics g, Pen p) : base(g, p) { } public override void BuildHead() { g.DrawEllipse(p, 50, 20, 30, 30); } public override void BuildBody() { g.DrawEllipse(p, 45, 50,40, 50); } public override void BuildArmLeft() { g.DrawLine(p, 50, 50, 30, 100); } public override void BuildArmRight() { g.DrawLine(p, 80, 50, 100, 100); } public override void BuildLegLeft() { g.DrawLine(p, 60, 100, 45, 150); } public override void BuildLegRight() { g.DrawLine(p, 70, 100, 85, 150); } } class PersonDirector//指挥建造类(隔离用户和建造过程的关联) { private PersonBuilder pb; public PersonDirector(PersonBuilder pb)//传递 需要建设什么样的人(高矮胖瘦) { this.pb = pb; } public void CreatePerson() { pb.BuildHead(); pb.BuildBody(); pb.BuildArmLeft(); pb.BuildArmRight(); pb.BuildLegLeft(); pb.BuildLegRight(); } } } private void button1_Click(object sender, EventArgs e) { Pen p = new Pen(Color.Yellow);//画笔颜色 PersonThinBuilder ptb = new PersonThinBuilder(pictureBox1.CreateGraphics(), p);//建立胖人 对象 PersonDirector pdThin = new PersonDirector(ptb);//建立构建者对象,传递胖人对象 pdThin.CreatePerson();//构建胖人 PersonFatBuilder pfb = new PersonFatBuilder(pictureBox2.CreateGraphics(), p); PersonDirector pdFat = new PersonDirector(pfb); pdFat.CreatePerson(); }
三,建造者模式解析
using System; using System.Collections.Generic; using System.Text; namespace 建造者模式 { class Product { IList<string> parts = new List<string>(); public void Add(string part) //添加产品部件 { parts.Add(part); } public void Show() //列举产品部件 { Console.WriteLine("\n产品 创建 ----"); foreach (string part in parts) { Console.WriteLine(part); } } } abstract class Builder//抽象类,规定必须实现的三个部分 { public abstract void BuildPartA(); public abstract void BuildPartB(); public abstract Product GetResult(); } class ConcreteBuilder1 : Builder //具体的建造者类,继承抽象类并实现其中所有接口 { private Product product = new Product(); public override void BuildPartA() { product.Add("部件A"); } public override void BuildPartB() { product.Add("部件B"); } public override Product GetResult() { return product; } } class ConcreteBuilder2 : Builder //具体建造者类 { private Product product = new Product(); public override void BuildPartA() { product.Add("部件X"); } public override void BuildPartB() { product.Add("部件Y"); } public override Product GetResult() { return product; } } class Director //整体实现各个子模块 { public void Construct(Builder builder)//传入的是抽象类,可以真正传入具体实现类的对象。 { builder.BuildPartA(); builder.BuildPartB(); } } class Program { static void Main(string[] args) { Director director = new Director(); Builder b1 = new ConcreteBuilder1(); Builder b2 = new ConcreteBuilder2(); director.Construct(b1);//指挥者用Builder1 构建产品 Product p1 = b1.GetResult();//获取构建的产品 p1.Show(); director.Construct(b2); Product p2 = b2.GetResult(); p2.Show(); Console.Read(); } } }