创建型模式之建造者模式

一、 定义


建造者模式(Builder):将一个复杂对象的构建与它的表示分离,似的同样的构建过程可以创建不同的表示。


  自己的理解:这个模式适用的场景是要建一些复杂的对象,但是这些对象建造的过程即构建大体一致,只是最后呈现出的结果不一样而已。举个例子,我要盖一个房子,不管什么类型的房子,盖的时候都要打地基,盖出框架,装上门,窗等,有一个共同的工序。但是最终展示出来的到底是几层,有几个门,门的材料,大小等这个是可变的。将客户端与创建过程分离,用户不用知道房子是怎么建的,只需清楚自己要什么样的房子,然后把条件输入就等着房子盖好就OK了。符合开闭原则。这样我们可以把不变的部分和变化的部分分离,都抽象出类,这样提高软件的扩展性,维护性和复用性。

二、 UML类图



Builder(创建者):提供创建产品的一个接口
ConcreteBuilder(具体创建者):实现Builder接口以构造和装配产品的各部件。
Director(指挥者):构造一个使用Builder接口的对象。

三、代码示例(创建小人)

<span style="font-family:KaiTi_GB2312;">namespace 建造者模式
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

      

        private void btnDrawPerson_Click(object sender, EventArgs e)
        {
            Pen p = new Pen(Color.Blue );
            PersonThinBuilder ptb = new PersonThinBuilder(picShow.CreateGraphics(), p);
            PersonDirector pdThin = new PersonDirector(ptb);
            pdThin.CreatePerson();
        }
    }

    abstract class PersonBuilder
    {
        protected Graphics g;
        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, 70, 50, 90, 100);
        }

        public override void BuildArmRight()
        {
            g.DrawLine(p, 70, 100, 85, 150);
        }

        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();
        }
    }
}
</span>

四、 适用环境和优缺点


适用环境:产品有差异但是建造过程大致一样


优点:

           1、建造时抽象出了建造者接口和具体的建造者类。如果要修改建造过程可以只改Builder接口,如果需要增加新的产品,只需抽象出新的ConcreteBuilder类就行了,保证了软件的可维护性和可扩展性。

           2、使用Director(指挥者)使得客户端不知道产品到底是怎么建造的,实现了构建和表示的分离,体现了开闭原则。

缺点:

           1、如果产品之间的差异很大,共同的组成部分或共同的建造过程不明显就不能使用该模式 。

           2、如果产品内部变化大,可能需要增加更多的ConcreteBuilder类来实现,这就会是系统变的复杂。

五、感悟

现在又一个疑惑:机房收费系统中涉及到了好多组合查询,一开始想他们的建造过程大致一样,都是判断第一行选中了没,第二行选中了没等等呢过,只是有些细微的差别,能不能用建造者模式?后来一想记得好几个窗体都是三个查询组合到一起,好像连命名都一样,那为什么不用原型模式呢,直接复制再稍微改改不就好了吗?后来再一想复制的基本上都是一样的,我第一个要是三个查询组合,之后都是三个,我要是再加第四个,第五的时候就不好更改了,不符合开闭原则,pass掉。用建造者模式的话可以把创建一个查询写到建造者接口中,想要几个组合查询就写几个具体建造者类呗。
只是瞎想想,具体指挥者的类写什么我还不太清楚,到底这个模式合不合适等重构的时候再细想吧。



    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值