设计模式- 建造者模式

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

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

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

  假设你是一个帮别人组装电脑主机的人,那么可以说,这时你就是充当建造者设计模式里指挥者这么一个角色。试想一下你要怎么样帮客户组装一台主机?装主机的人一般会先确定客户需要的主机配置,例如客户要求主板用华硕的,内存用金斯顿的,硬盘用西部数据的,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();
 
         }


 

我的博客园原文地址:http://www.cnblogs.com/cxeye/archive/2012/08/26/2657408.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值