C#设计模式-建造者模式

在软件系统中,有时需要创建一个复杂对象,并且这个复杂对象由其各部分子对象通过一定的步骤组合而成。

例如一个采购系统中,如果需要采购员去采购一批电脑时,在这个实际需求中,电脑就是一个复杂的对象,它是由CPU、主板、硬盘、显卡、机箱等组装而成的,如果此时让采购员一台一台电脑去组装的话真是要累死采购员了,这里就可以采用建造者模式来解决这个问题,我们可以把电脑的各个组件的组装过程封装到一个建造者类对象里,建造者只要负责返还给客户端全部组件都建造完毕的产品对象就可以了。然而现实生活中也是如此的,如果公司要采购一批电脑,此时采购员不可能自己去买各个组件并把它们组织起来,此时采购员只需要像电脑城的老板说自己要采购什么样的电脑就可以了,电脑城老板自然会把组装好的电脑送到公司。

一、 建造者(Builder)模式

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

建造者模式使得建造代码与表示代码的分离,可以使客户端不必知道产品内部组成的细节,从而降低了客户端与具体产品之间的耦合度。

二、 建造者模式的类图

三、 建造者模式的实现

在这个例子中,电脑城的老板是直接与客户(也就是指采购员)联系的,然而电脑的组装是由老板指挥装机人员去把电脑的各个部件组装起来,真真负责创建产品(这里产品指的就是电脑)的人就是电脑城的装机人员。理清了这个逻辑过程之后,下面就具体看下如何用代码来表示这种现实生活中的逻辑过程:

using System;
using System.Collections.Generic;

/// <summary>
/// 以组装电脑为例子
/// 每台电脑的组成过程都是一致的,但是使用同样的构建过程可以创建不同的表示(即可以组装成不一样的电脑,配置不一样)
/// 组装电脑的这个场景就可以应用建造者模式来设计
/// </summary>
namespace BuilderPattern
{
    /// <summary>
    /// 客户类
    /// </summary>
    class Customer
    {
        static void Main(string[] args)
        {
            // 客户找到电脑城老板说要买电脑,这里要装两台电脑
            // 创建指挥者和构造者
            var director = new Director();
            Builder b1 = new ConcreteBuilder1();
            Builder b2 = new ConcreteBuilder2();

            // 老板叫员工去组装第一台电脑
            director.Construct(b1);

            // 组装完,组装人员搬来组装好的电脑
            Computer computer1 = b1.GetComputer();
            computer1.Show();

            // 老板叫员工去组装第二台电脑
            director.Construct(b2);
            Computer computer2 = b2.GetComputer();
            computer2.Show();

            Console.Read();
        }
    }

    /// <summary>
    /// 小王和小李难道会自愿地去组装嘛,谁不想休息的,这必须有一个人叫他们去组装才会去的
    /// 这个人当然就是老板了,也就是建造者模式中的指挥者
    /// 指挥创建过程类
    /// </summary>
    public class Director
    {
        // 组装电脑
        public void Construct(Builder builder)
        {
            builder.BuildPartCpu();
            builder.BuildPartMainBoard();
        }
    }

    /// <summary>
    /// 电脑类
    /// </summary>
    public class Computer
    {
        // 电脑组件集合
        private readonly IList<string> _parts = new List<string>();

        // 把单个组件添加到电脑组件集合中
        public void Add(string part)
        {
            _parts.Add(part);
        }

        public void Show()
        {
            Console.WriteLine("电脑开始在组装.......");
            foreach (string part in _parts)
            {
                Console.WriteLine("组件" + part + "已装好");
            }

            Console.WriteLine("电脑组装好了");
        }
    }

    /// <summary>
    /// 抽象建造者,这个场景下为 "组装人" ,这里也可以定义为接口
    /// </summary>
    public abstract class Builder
    {
        // 装CPU
        public abstract void BuildPartCpu();
        // 装主板
        public abstract void BuildPartMainBoard();

        // 当然还有装硬盘,电源等组件,这里省略

        // 获得组装好的电脑
        public abstract Computer GetComputer();
    }

    /// <summary>
    /// 具体创建者,具体的某个人为具体创建者,例如:装机小王啊
    /// </summary>
    public class ConcreteBuilder1 : Builder
    {
        readonly Computer _computer = new Computer();
        public override void BuildPartCpu()
        {
            _computer.Add("CPU1");
        }

        public override void BuildPartMainBoard()
        {
            _computer.Add("Main board1");
        }

        public override Computer GetComputer()
        {
            return _computer;
        }
    }

    /// <summary>
    /// 具体创建者,具体的某个人为具体创建者,例如:装机小李啊
    /// 又装另一台电脑了
    /// </summary>
    public class ConcreteBuilder2 : Builder
    {
        readonly Computer _computer = new Computer();
        public override void BuildPartCpu()
        {
            _computer.Add("CPU2");
        }

        public override void BuildPartMainBoard()
        {
            _computer.Add("Main board2");
        }

        public override Computer GetComputer()
        {
            return _computer;
        }
    }
}

上面代码中都有详细的注释代码,这里就不过多解释,大家可以参考代码和注释来与现实生活中的例子做对比,下图展示了上面代码的运行结果:

电脑开始在组装……
组件CPU1已装好
组件Main board1已装好
电脑组装好了
电脑开始在组装……
组件CPU2已装好
组件Main board2已装好
电脑组装好了

四、 .NET 中建造者模式的实现

前面的设计模式在.NET类库中都有相应的实现,那在.NET 类库中,是否也存在建造者模式的实现呢? 然而对于疑问的答案是肯定的,在.NET 类库中,System.Text.StringBuilder(存在mscorlib.dll程序集中)就是一个建造者模式的实现。不过它的实现属于建造者模式的演化,此时的建造者模式没有指挥者角色和抽象建造者角色,StringBuilder类即扮演着具体建造者的角色,也同时扮演了指挥者和抽象建造者的角色,此时建造模式的实现如下:

using System;
using System.Collections.Generic;

/// <summary>
/// 建造者模式的演变
/// 省略了指挥者角色和抽象建造者角色
/// 此时具体建造者角色扮演了指挥者和建造者两个角色
/// </summary>
public class Builder
{
    // 具体建造者角色的代码
    private readonly Product _product = new Product();
    public void BuildPartA()
    {
        _product.Add("PartA");
    }
    public void BuildPartB()
    {
        _product.Add("PartB");
    }
    public Product GetProduct()
    {
        return _product;
    }
    // 指挥者角色的代码
    public void Construct()
    {
        BuildPartA();
        BuildPartB();
    }
}

/// <summary>
/// 产品类
/// </summary>
public class Product
{
    // 产品组件集合
    private readonly IList<string> _parts = new List<string>();

    // 把单个组件添加到产品组件集合中
    public void Add(string part)
    {
        _parts.Add(part);
    }

    public void Show()
    {
        Console.WriteLine("产品开始在组装.......");
        foreach (string part in _parts)
        {
            Console.WriteLine("组件" + part + "已装好");
        }

        Console.WriteLine("产品组装完成");
    }
}

// 此时客户端也要做相应调整
class Client
{
    private static Builder _builder;
    static void Main(string[] args)
    {
        _builder = new Builder();
        _builder.Construct();
        Product product = _builder.GetProduct();
        product.Show();
        Console.Read();
    }
}

五、 建造者模式的分析

建造模式的实现要点:

  1. 建造者模式中,指挥者是直接与客户端打交道的,指挥者将客户端创建产品的请求划分为对各个部件的建造请求,再将这些请求委派到具体建造者角色,具体建造者角色是完成具体产品的构建工作的,却不为客户所知道。
  2. 建造者模式主要用于“分步骤来构建一个复杂的对象”,其中“分步骤”是一个固定的组合过程,而复杂对象的各个部分是经常变化的(也就是说电脑的内部组件是经常变化的,这里指的的变化如硬盘的大小变了,CPU由单核变双核等)。
  3. 产品不需要抽象类,由于建造模式的创建出来的最终产品可能差异很大,所以不大可能提炼出一个抽象产品类。
  4. 在前面文章中介绍的抽象工厂模式解决了“系列产品”的需求变化,而建造者模式解决的是 “产品部分” 的需要变化。
  5. 由于建造者隐藏了具体产品的组装过程,所以要改变一个产品的内部表示,只需要再实现一个具体的建造者就可以了,从而能很好地应对产品组成组件的需求变化。

六、 总结

到这里,建造者模式的介绍就结束了,建造者模式(Builder Pattern),将一个复杂对象的构建与它的表示分离,使的同样的构建过程可以创建不同的表示。建造者模式的本质是使组装过程(用指挥者类进行封装,从而达到解耦的目的)和创建具体产品解耦,使我们不用去关心每个组件是如何组装的。

时间: 2024-10-18 04:32:17

C#设计模式-建造者模式的相关文章

设计模式—建造者模式(Builder)

title: 设计模式-建造者模式 建造者模式(Builder)是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节.建造者模式属于对象创建型模式.我们获得一个对象的时候不是直接new这个对象出来,而是对其建造者进行属性设置,然后建造者在根据设置建造出各个对象出来.建造者模式又可以称为生成器模式. 模式结构 一个标准的建造者模式包含如下角色: Builder:抽象建造者 ConcreteBuilder:具体建造者 Director

小菜学设计模式——建造者模式

背景 不要小看炒菜这件小事上,想要上一道佳肴,那是需要循规蹈矩,步步小心的.我相信你肯定在外面吃过没放盐的快餐,吃过放多了盐的快餐.....既然炒菜是一个如此复杂的过程,又必须循规蹈矩,那为什么不给他一个死规定呢?如果谁没有按照规定做事,就进行对应的提醒警告.这就是建造者模式的由来,限制规则步骤,但是开发规则细节.比如说盛菜之前必须放盐,那么规定一定要放盐,具体放多少自己论情况而定. 1.使用意图 如果你需要将一个复杂对象的构建与它的表示(构建具体过)分离,使得同样的构建过程可以创建不同的表示的

设计模式——建造者模式

HeadFirst中并没有把建造者模式(生成器模式)当做常用的设计模式来讲解,只是在附录中一带而过. 建造者模式的本质:       分离了对象组件的单独构造(由Builder来负责)和装配(由Director)来负责.从而可以构建出复杂的对象.这个模式适用于:某个对象的构建       过程复杂的情况先使用.由于实现了构建和装配的解耦.不同的构建器,相同的装配,也可以做出不同的对象相同的构建器不同的装配顺序也可以 做出不同的对象.也就是实现了构建算法.装配算法的解耦,实现了更好的复用. Dem

C#设计模式——建造者模式(Builder Pattern)

1.建造者模式简介 1.1>.定义 建造者模式(Builder)将复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示. 1.2>.使用频率  中低 1.3>.原型模式应用 在软件系统中,有时候面临一个复杂对象的创建工作,该对象通常由各个部分子对象用一定的算法构成,或者按一定的步骤组合而成:这些算法和步骤是稳定的,而构成这个对象的子对象却经常由于需求的变化而不断变化. 生活中的例子,要组装一台电脑,它的组装过程基本是不变的,都可以由主板.CPU.内存等按照某个稳定方式组合而成.

Java设计模式——建造者模式

建造者模式(Builder Pattern)属于创建形的设计模式,使用多个简单的对象一步一步构建成一个复杂的对象. 主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成:由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定. 何时使用:一些基本部件不会变,而其组合经常变化的时候. 应用实例: 1.去肯德基,汉堡.可乐.薯条.炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的&quo

Python设计模式——建造者模式

需求,画人物,要求画一个人的头,左手,右手,左脚,右脚和身体,画一个瘦子,一个胖子 不使用设计模式 #encoding=utf-8 __author__ = '[email protected]' if __name__=='__name__': print '画左手' print '画右手' print '画左脚' print '画右脚' print '画胖身体' print '画左手' print '画右手' print '画左脚' print '画右脚' print '画瘦身体' 这样写的

php设计模式 — 建造者模式

需求分析: 我们接到了一个订单,是宝马公司和奔驰公司的,他们负责定义产品的零部件以及型号,我们负责生产,需求简单的描述就是这样. 我们需要为这个需求设计一个设计模式去更好的适应他们的需求. 首先我们需要一个车模型类,来定义好需要的所有零部件,这就叫做抽象类,之所以这样是因为我们还有可能接到更多公司的订单,比如劳斯莱斯,宾利. 然后由各自的车来继承这个抽象类,实现里面的方法. 接下来就需要一个建造者抽象类,来定义建造各自的车需要的方法 然后由各自车建造者来继承这个抽象类. 我们会想到一个建造模式了

C++设计模式——建造者模式

建造者模式 在GOF的<设计模式 可复用面向对象软件的基础>中是这样说的:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 这句话,似懂非懂的.一个复杂对象的创建,其通常是由很多的子对象构成:如果一个对象能够直接就创建好了,那么也不会称之为复杂对象.由于项目中需求的变化,这个复杂对象的各个部分经常会发生剧烈的变化,但是,不管怎么变化,将它们组合在一起,组成一个复杂的对象的事实是不会变的.建造者模式就提供了一种“封装机制”来将各个对象的变化隔离开,最终,组合成复杂对象的

PHP设计模式——建造者模式

声明:本系列博客参考资料<大话设计模式>,作者程杰. 建造者模式也称生成器模式,核心思想是将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式. 例如:汽车,他的发动机引擎有好多品牌,轮胎也有各种材质,内饰更是千奇百怪:鸟,他的头.翅膀以及脚有各种颜色和形状,在创建这种复杂对象的时候,我们建议使用建造者模式. 类图: 建造者模式一般认为有四个角色: 1.产品角色,产品角色定义自身的组成属性 2.抽象建造者,抽象建造者定义了产品的创建过程以及如何