您的位置:首页 > 其它

设计模式- 建造者模式

2012-10-23 15:43 211 查看
  其实有很多设计模式并没有像网上一些文章那样写的很复杂,理解了一下后发现他的实现原理很清晰。比如建造者设计模式。

  建造者设计模式又叫生成器模式,我们不要叫他生成器模式,我觉的这个名字不好听。我比较喜欢建造者设计模式这个名字。

 先来了解一下建造者设计模式是什么?

  假设你是一个帮别人组装电脑主机的人,那么可以说,这时你就是充当建造者设计模式里指挥者这么一个角色。试想一下你要怎么样帮客户组装一台主机?装主机的人一般会先确定客户需要的主机配置,例如客户要求主板用华硕的,内存用金斯顿的,硬盘用西部数据的,CPU用因特尔的,电源用航嘉的,机箱用长城的……,先确定好后,再进行组装主机。

  作为装主机的人(指挥者),你根据客户提供的配置去装主机。但装主机时,先装主板还是先装硬盘,完全由你决定。具体装的过程,内部实现细节,客户不必去关心。对于客户而言他们只是需要提供他们所需要的主机配置清单而以。

  那么对于装主机的人,他是这个设计模式里唯一的,不变的部份,所有的客户都是找他装,所以在C#里可以把装主机的人写成一个单独的类,他的工作就是接收不同客户传递过来给他配置清单进行组装主机。

  而变化的部份是不同的主机配置清单,那么我们可以变化的这部份写一个抽象类,例如如下代码:

  public abstract class ComputerBuilder
  {
        public abstract void MainBoard();//主板
    public abstract void CPU();//CPU
  public abstract void Memory();//内存
    public abstract void HardDisk();//硬盘
    public abstract void PowerSupply();//电源
  }

  接着由不同的客户实现不同的抽象类:

//客户A需要实现的主机配置
public class CustomerA : ComputerBuilder
{
public override void CPU()
{
Console.WriteLine("AMD2代");
}

public override void MainBoard()
{
Console.WriteLine("华硕M4N68T-MLE");
}

public override void HardDisk()
{
Console.WriteLine("西部数据500G");
}

public override void Memory()

{
Console.WriteLine("金斯顿2G");
}

public override void PowerSupply()
{
Console.WriteLine("技展450w ");
}
}

//客户B需要实现的主机配置
public class CustomerB : ComputerBuilder
{
public override void CPU()
{
Console.WriteLine("AMD Athlon64 X2 3800+ AM2");
}

public override void MainBoard()
{
Console.WriteLine("华硕 M2V");
}

public override void HardDisk()
{
Console.WriteLine("希捷 160G");
}

public override void Memory()
{
Console.WriteLine("威刚VDATA 1GB DDRII667");
}

public override void PowerSupply()
{
Console.WriteLine("Tt XP355(W3006)");
}
}

从这个例子我们看出在建造者设计模式有哪些东西,有要抽象实现的方法(也就是装主机的人需要的配置,一个一个的配置可以当作一个一个的方法)。和一个建设者类(也就是装主机的人),里面有一个指挥者方法(Director)。



  那么建造者设计模式可以应用在哪些场合?

  在《大话设计模式》里面是这么说的:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示意图。这时候就用到了建造者模式。

  读这句话的时候,我也不知道他在讲什么。但是看了里面给的代码,把思路搞清楚后再回过头来看这句,就看懂了。

  还是以上面的组装电脑主机的例子来解释一下《大话设计模式》里的这句话。组装电脑的人,他组装电脑先后顺序已经做习惯了,这个过程不会改后,而且组装电脑需要的东西主板、内存、硬盘、CPU、电源这些是不会变的,但是他们的所需要的型号或者大小会变,例如客户不是要1G的金斯顿内存,他要2G的金斯顿内存,客户可能不要250G大小的西部数据硬盘,他要500G的三星硬盘。这些可都是会变化的。所以大话设计模式里的这句“使得同样的构建过程可以创建不同的表示意图”,意思就可以这么理解成配置的东西内存、主板、硬盘这些和组装电脑的过程这些都是确定的,可是配置的型号和大小的可能不同,例如可能是要2G的内存或者是4G的内存等等,所以我们可以根据一定的装机需求,不同的型号和大小就能组装出不同性能的主机来,也就是上面的创建不同的表示意图出来这句一个道理。不知道这么说好不好理解!

  好了,最后我们还是贴一下自己写的代码和大话设计模式那个例子的代码。另外我看了一个博客:http://www.cnblogs.com/lovecherry/ 他里面有篇 无废话C#设计模式之六:Builder。我的例子就是参看他后写的。

  自己写的代码例子:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 建造者模式_装主机
{
class Program
{
static void Main(string[] args)
{

ComputerDirector cd = null;

CustomerA ca = new CustomerA();
cd = new ComputerDirector(ca);
cd.CreateComputer();

CustomerB cb = new CustomerB();
cd = new ComputerDirector(cb);
cd.CreateComputer();

Console.ReadLine();
}
}

public class ComputerDirector
{
private ComputerBuilder cb;
public ComputerDirector(ComputerBuilder cb)
{
this.cb = cb;
}

public void CreateComputer()
{
//开始装电脑,先装那个由装主机的指挥者决定
cb.CPU();
cb.MainBoard();
cb.Memory();
cb.PowerSupply();
cb.HardDisk();
}
}

public abstract class ComputerBuilder
{
public abstract void MainBoard();//主板
public abstract void CPU();//CPU
public abstract void Memory();//内存
public abstract void HardDisk();//硬盘
public abstract void PowerSupply();//电源
}

//客户A需要实现的主机配置
public class CustomerA : ComputerBuilder
{
public override void CPU()
{
Console.WriteLine("AMD2代");
}

public override void MainBoard()
{
Console.WriteLine("华硕M4N68T-MLE");
}

public override void HardDisk()
{
Console.WriteLine("西部数据500G");
}

public override void Memory()
{
Console.WriteLine("金斯顿2G");
}

public override void PowerSupply()
{
Console.WriteLine("技展450w ");
}
}

//客户B需要实现的主机配置
public class CustomerB : ComputerBuilder
{
public override void CPU()
{
Console.WriteLine("AMD Athlon64 X2 3800+ AM2");
}

public override void MainBoard()
{
Console.WriteLine("华硕 M2V");
}

public override void HardDisk()
{
Console.WriteLine("希捷 160G");
}

public override void Memory()
{
Console.WriteLine("威刚VDATA 1GB DDRII667");
}

public override void PowerSupply()
{
Console.WriteLine("Tt XP355(W3006)");
}
}
}

  大话设计模式代码如下,画人的建造者模式的主要代码,写成一个PersonBuilder类:

namespace 建造者模式
{
//指挥者
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();
}
}

//要实现的抽象方法
abstract class PersonBuilder
{
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
{
private Graphics g;
private Pen p;

public PersonThinBuilder(Graphics g, Pen p)
{
this.g = g;
this.p = 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
{
private Graphics g;
private Pen p;

public PersonFatBuilder(Graphics g, Pen p)
{
this.g = g;
this.p = 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);
}
}
}

  WinForm里面的代码:

private void button1_Click(object sender, EventArgs e)
{
//画笔
Pen p = new Pen(Color.Red);

//画一个瘦人
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();

}


我的博客园原文地址:/article/6583691.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: