建造者模式(Builder)定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
使用场景:
创建复杂对象的算法应该独立于该对象的组成部分,以及他们的装配方式时。
当构造过程必须允许被构造的对象有不同表示时。
例子背景:甲方需求是画出胖小人或瘦小人,到底要画哪个不确定,并且不想了解画小人的过程。乙方把任务交给指挥者,让画胖小人的画手1和画瘦小人的画手2都听指挥者的命令,指挥者知道画图的方法是画头、画身子、画四肢。指挥者让谁画谁就画,并且监督画手严格按照画图方法来画,绝不会导致画的图缺胳膊少腿,这样两个画手通过一样的画图方法分别画出了胖小人和瘦小人。
建造人类:抽象类
abstract class PersonBuilder //建造小人是个抽象类 { protected Graphics g; //添加命名空间using System.Drawing; protected Pen p; public PersonBuilder(Graphics g, Pen p) //构造方法重载 { this.g = g; this.p = p; } //全部是抽象方法 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); } }
建造胖小人略,改改画图参数即可。
Director指挥者类:指挥建造过程
class PersonDirector //建造指挥者 { private PersonBuilder pb; //甲方告诉指挥者需要什么样的小人,这里pb可以是PersonBuilder类或它的子类对象 public PersonDirector(PersonBuilder pb) { this.pb = pb; } public void CreatePerson() //不同的子类对象调用各自的内部方法 { pb.BuildHead(); pb.BuildBody(); pb.BuildArmLeft(); pb.BuildArmRight(); pb.BuildLegLeft(); pb.BuildLegRight(); } }
窗体代码:客户不需要知道具体建造过程
Pen p = new Pen(Color.Yellow); private void pictureBox1_Click(object sender, EventArgs e) { //CreateGraphics ()方法的作用是为控件创建Graphics PersonThinBuilder ptb = new PersonThinBuilder(pictureBox1 .CreateGraphics (),p); PersonDirector pdThin = new PersonDirector(ptb); pdThin.CreatePerson()//指挥用画瘦小人的方法画图 } private void pictureBox2_Click(object sender, EventArgs e) { PersonFatBuilder pfb = new PersonFatBuilder(pictureBox2 .CreateGraphics (),p); PersonDirector pdFat = new PersonDirector(pfb); pdFat.CreatePerson();//指挥用画胖小人的方法画图 } }