C#设计模式之四建造者模式(Builder Pattern)【创建型】

原文:C#设计模式之四建造者模式(Builder Pattern)【创建型】

一、引言

今天我们要讲讲Builder模式,也就是建造者模式,当然也有叫生成器模式的,英文名称是Builder Pattern。在现实生活中,我们经常会遇到一些构成比较复杂的物品,比如:电脑,它就是一个复杂的物品,它主要是由CPU、主板、硬盘、显卡、机箱等组装而成的。手机当然也是复杂物品,由主板,各种芯片,RAM 和ROM  摄像头之类的东西组成。但是无论是电脑还是手机,他们的组装过程是固定的,就拿手机来说,组装流水线是固定的,不变的,但是把不同的主板和其他组件组装在一起就会生产出不同型号的手机。那么在软件系统中是不是也会存在这样的对象呢?答案是肯定的。在软件系统中我们也会遇到类似的复杂对象,并且这个复杂对象的各个部分按照一定的算法组合在一起,此时该对象的创建工作就可以使用Builder模式了,下面我就来详细看看这个模式吧。

二、建造者模式的详细介绍

2.1、动机(Motivate)

在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。如何应对这种变化?如何提供一种“封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”不随着需求改变而改变?

2.2、意图(Intent)

将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。                   ——《设计模式》GoF

2.3、结构图(Structure)
   
2.4、模式的组成

(1)、抽象建造者角色(Builder):为创建一个Product对象的各个部件指定抽象接口,以规范产品对象的各个组成成分的建造。一般而言,此角色规定要实现复杂对象的哪些部分的创建,并不涉及具体的对象部件的创建。

(2)、具体建造者(ConcreteBuilder)

1)实现Builder的接口以构造和装配该产品的各个部件。即实现抽象建造者角色Builder的方法。

2)定义并明确它所创建的表示,即针对不同的商业逻辑,具体化复杂对象的各部分的创建

3) 提供一个检索产品的接口

4) 构造一个使用Builder接口的对象即在指导者的调用下创建产品实例

  (3)、指导者(Director):调用具体建造者角色以创建产品对象的各个部分。指导者并没有涉及具体产品类的信息,真正拥有具体产品的信息是具体建造者对象。它只负责保证对象各部分完整创建或按某种顺序创建。

  (4)、产品角色(Product):建造中的复杂对象。它要包含那些定义组件的类,包括将这些组件装配成产品的接口。

2.5 建筑者模式的具体实现

现在人们生活水平都提高了,家家都有了家庭轿车,那今天我们就以汽车组装为例来说明Builder模式的实现。

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5
  6
  7 /// <summary>
  8 /// 现在人们的生活水平都提高了,有钱了,我今天就以汽车组装为例子
  9 /// 每台汽车的组装过程都是一致的,所以我们使用同样的构建过程可以创建不同的表示(即可以组装成不同型号的汽车,不能像例子这样,一会别克,一会奥迪的)
 10 /// 组装汽车、电脑、手机、电视等等负责对象的这些场景都可以应用建造者模式来设计
 11 /// </summary>
 12 namespace 设计模式之建造者模式
 13 {
 14     /// <summary>
 15     /// 客户类
 16     /// </summary>
 17     class Customer
 18     {
 19         static void Main(string[] args)
 20         {
 21             Director director = new Director();
 22             Builder buickCarBuilder = new BuickBuilder();
 23             Builder aoDiCarBuilder = new AoDiBuilder();
 24
 25             director.Construct(buickCarBuilder);
 26
 27             //组装完成,我来驾驶别克了
 28             Car buickCar = buickCarBuilder.GetCar();
 29             buickCar.Show();
 30
 31             // 我老婆就要奥迪了,她比较喜欢大品牌
 32             director.Construct(aoDiCarBuilder);
 33             Car aoDiCar = aoDiCarBuilder.GetCar();
 34             aoDiCar.Show();
 35
 36             Console.Read();
 37         }
 38     }
 39
 40     /// <summary>
 41     /// 这个类型才是组装的,Construct方法里面的实现就是创建复杂对象固定算法的实现,该算法是固定的,或者说是相对稳定的
 42     /// 这个人当然就是老板了,也就是建造者模式中的指挥者
 43     /// </summary>
 44     public class Director
 45     {
 46         // 组装汽车
 47         public void Construct(Builder builder)
 48         {
 49             builder.BuildCarDoor();
 50             builder.BuildCarWheel();
 51             builder.BuildCarEngine();
 52         }
 53     }
 54
 55     /// <summary>
 56     /// 汽车类
 57     /// </summary>
 58     public sealed class Car
 59     {
 60         // 汽车部件集合
 61         private IList<string> parts = new List<string>();
 62
 63         // 把单个部件添加到汽车部件集合中
 64         public void Add(string part)
 65         {
 66             parts.Add(part);
 67         }
 68
 69         public void Show()
 70         {
 71             Console.WriteLine("汽车开始在组装.......");
 72             foreach (string part in parts)
 73             {
 74                 Console.WriteLine("组件" + part + "已装好");
 75             }
 76
 77             Console.WriteLine("汽车组装好了");
 78         }
 79     }
 80
 81     /// <summary>
 82     /// 抽象建造者,它定义了要创建什么部件和最后创建的结果,但是不是组装的的类型,切记
 83     /// </summary>
 84     public abstract class Builder
 85     {
 86         // 创建车门
 87         public abstract void BuildCarDoor();
 88         // 创建车轮
 89         public abstract void BuildCarWheel();
 90         //创建车引擎
 91         public abstract void BuildCarEngine();
 92         // 当然还有部件,大灯、方向盘等,这里就省略了
 93
 94         // 获得组装好的汽车
 95         public abstract Car GetCar();
 96     }
 97
 98     /// <summary>
 99     /// 具体创建者,具体的车型的创建者,例如:别克
100     /// </summary>
101     public sealed class BuickBuilder : Builder
102     {
103         Car buickCar = new Car();
104         public override void BuildCarDoor()
105         {
106             buickCar.Add("Buick‘s Door");
107         }
108
109         public override void BuildCarWheel()
110         {
111             buickCar.Add("Buick‘s Wheel");
112         }
113
114         public override void BuildCarEngine()
115         {
116             buickCar.Add("Buick‘s Engine");
117         }
118
119         public override Car GetCar()
120         {
121             return buickCar;
122         }
123     }
124
125     /// <summary>
126     /// 具体创建者,具体的车型的创建者,例如:奥迪
127     /// </summary>
128     public sealed class AoDiBuilder : Builder
129     {
130         Car aoDiCar = new Car();
131         public override void BuildCarDoor()
132         {
133             aoDiCar.Add("Aodi‘s Door");
134         }
135
136         public override void BuildCarWheel()
137         {
138             aoDiCar.Add("Aodi‘s Wheel");
139         }
140
141         public override void BuildCarEngine()
142         {
143             aoDiCar.Add("Aodi‘s Engine");
144         }
145
146         public override Car GetCar()
147         {
148             return aoDiCar;
149         }
150     }
151 }

上面代码中都有详细的注释代码,这里就不过多解释。

三、建造者模式的实现要点

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

3.1】、建造者模式的优点:

(1)、使用建造者模式可以使客户端不必知道产品内部组成的细节。

(2)、具体的建造者类之间是相互独立的,容易扩展。

(3)、由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生任何影响。

 3.2】、建造者模式的缺点:

(1)、产生多余的Build对象以及Dirextor类。

 3.3】、创建者模式的使用场景:

(1)、当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。

(2)、相同的方法,不同的执行顺序,产生不同的事件结果时。

(3)、多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时。

(4)、产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能。

(5)、创建一些复杂的对象时,这些对象的内部组成构件间的建造顺序是稳定的,但是对象的内部组成构件面临着复杂的变化。

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

在微软的类库里面大量使用了设计模式,如果要想学习设计模式,仔细看看微软的类库是很有帮助的。今天的设计模式在FCL里面也有实现,该类型的名字就是System.Text.StringBuilder(存在mscorlib.dll程序集中),它就是一个建造者模式的实现,从名称也可以看出来。不过它的实现属于建造者模式的演化,此时的建造者模式没有指挥者角色和抽象建造者角色,StringBuilder类即扮演着具体建造者的角色,也同时扮演了指挥者和抽象建造者的角色,StringBuilder类扮演着建造string对象的具体建造者角色,其中的ToString()方法用来返回具体产品给客户端(相当于上面代码中GetProduct方法)。其中Append方法用来创建产品的组件(相当于上面代码中BuildPartA和BuildPartB方法),因为string对象中每个组件都是字符,所以也就不需要指挥者的角色的代码(指的是Construct方法,用来调用创建每个组件的方法来完成整个产品的组装),因为string字符串对象中每个组件都是一样的,都是字符,所以Append方法也充当了指挥者Construct方法的作用。

五、总结

今天就到这里了,还需要重申的是,学习设计模式不能死学,就像StringBuilder一样,他和Gof23种设计模式中定义的情形有很大的不同,但是它也是Builder模式,因为它们要解决的问题和使用场景是吻合的。我们写代码的时候,不要太居于形式,要看使用的契机和模式是否吻合,根据具体的情况我们的模式也会发生变化。当我们看得越多,写的越多时候,你的变化就越自然了。
  今天是2017年9月30日,明天就是国庆了,10月4日又是中秋,我在此祝大家节日快乐,工作顺利。我也要休息几天了,暂时就不写东西了。

原文地址:https://www.cnblogs.com/lonelyxmas/p/8342675.html

时间: 2024-10-16 20:21:45

C#设计模式之四建造者模式(Builder Pattern)【创建型】的相关文章

设计模式之建造者模式Builder(创建型)

1. 概述 在软件开发的过程中,当遇到一个“复杂的对象”的创建工作,该对象由一定各个部分的子对象用一定的算法构成,由于需求的变化,复杂对象的各个部分经常面临剧烈的变化,但将它们组合在一起的算法相对稳定. 例子1:买肯德基 典型的儿童餐包括一个主食,一个辅食,一杯饮料和一个玩具(例如汉堡.炸鸡.可乐和玩具车).这些在不同的儿童餐中可以是不同的,但是组合成儿童餐的过程是相同的.        客户端:顾客,想去买一套套餐(这里面包括汉堡,可乐,薯条),可以有1号和2号两种套餐供顾客选择.      

【转】设计模式(三)建造者模式Builder(创建型)

(http://blog.csdn.net/hguisu/article/details/7518060) 1. 概述 在软件开发的过程中,当遇到一个"复杂的对象"的创建工作,该对象由一定各个部分的子对象用一定的算法构成,由于需求的变化,复杂对象的各个部分经常面临剧烈的变化,但将它们组合在一起的算法相对稳定. 例子1:买肯德基 典型的儿童餐包括一个主食,一个辅食,一杯饮料和一个玩具(例如汉堡.炸鸡.可乐和玩具车).这些在不同的儿童餐中可以是不同的,但是组合成儿童餐的过程是相同的.   

设计模式(三)建造者模式Builder(创建型)

1. 概述 在软件开发的过程中,当遇到一个"复杂的对象"的创建工作,该对象由一定各个部分的子对象用一定的算法构成,由于需求的变化,复杂对象的各个部分经常面临剧烈的变化,但将它们组合在一起的算法相对稳定. 例子1:买肯德基 典型的儿童餐包括一个主食,一个辅食,一杯饮料和一个玩具(例如汉堡.炸鸡.可乐和玩具车).这些在不同的儿童餐中可以是不同的,但是组合成儿童餐的过程是相同的. 客户端:顾客,想去买一套套餐(这里面包括汉堡,可乐,薯条),可以有1号和2号两种套餐供顾客选择.       指

java设计模式之四建造者模式(Builder)

工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象,所谓复合对象就是指某个类具有不同的属性,其实建造者模式就是前面抽象工厂模式和最后的Test结合起来得到的.我们看一下代码: 还和前面一样,一个Sender接口,两个实现类MailSender和SmsSender.最后,建造者类如下: [java] view plaincopy public class Builder { private List<Sender> list = new ArrayL

建造者模式(Builder Pattern)

模式定义 造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. UML类图 Builder:抽象建造者 ConcreteBuilder:具体建造者 Director:指挥者 Product:产品角色 代码结构 public static class BuilderApp { public static void Run() { Director director = new Director(); Builder b1 = new

设计模式(创建型)之建造者模式(Builder Pattern)

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! 概述 建造者模式将客户端与包含多个组成部分的复杂对象的创建过程分离,客户端压根不用知道复杂对象的内部组成部分与装配方式,只需要知道所需建造者的类型即可.它关注如何一步一步创建一个的复杂对象,不同的具体建造者定义了不同的创建过程,且具体建造者相互独立,增加新的建造者非常方便,无须修改已有代码,系统具有较好的扩展性. 问题来了... 你可能会有疑惑,建造者模式和抽象工

23种设计模式--建造者模式-Builder Pattern

一.建造模式的介绍       建造者模式就是将零件组装成一个整体,用官方一点的话来讲就是将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示.生活中比如说组装电脑,汽车等等这些都是建造者模式的具体体现,组装电脑反应到软件上就是一个复杂的对象,然后我们使用建造者模式的时候需要抽象一个建造类,抽象一个指挥者指挥具体实现的那个类,然后就是具体实现这个对象的类,这样就避免了每新创建一个不同的复杂对象就需要重新写一下这个类,这样就只要重写建造者就可以了,我们接下来就用组装电脑这个来说明一

设计模式之建造者模式——Builder

一.概述 Builder模式,中文名为建造者模式,又名生成器模式.构建者模式等,是创建型设计模式之一.用于将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 1.适用性: 对象的创建比较复杂.有多种创建形式时 创建复杂对象的算法与对象内部组成和装配是相对独立的 2.UML类图 Builder:定义创建Product各个部件的抽象接口 ConcreteBuilder:继承自Builder,实现创建具体类型的Product所有部件的接口,并提供一个获取最终产品的接口. Dir

5.建造者模式(Builder Pattern)

using System; using System.Collections.Generic; namespace ConsoleApplication4 { class Program { /// <summary> /// 以组装电脑为例子 /// 每台电脑的组成过程都是一致的,但是使用同样的构建过程可以创建不同的表示(即可以组装成不一样的电脑,配置不一样) /// 组装电脑的这个场景就可以应用建造者模式来设计 /// </summary> /// <param name