设计模式(0)简单工厂模式html
设计模式(2)工厂方法模式(Factory Method)github
设计模式(3)抽象工厂模式(Abstract Factory)算法
源码地址设计模式
建造者模式是一种常见的建立型模式,也称生成器模式。建造者模式的通常书面化定义为:将一个复杂对象的构建与该对象的表示分离,使得一样的构建过程能够建立不一样的表示ide
建造者模式主要用于构建复杂产品,而且该产品是能够步骤化或者模块化的,最终能够根据步骤或模块组装建立出一个复杂产品。模块化
现实生活中咱们天天都在使用的手机有不一样品牌不一样型号,千差万别,但他们都具备屏幕、电池、外壳、核心(CPU、GUPU、ROM、RAM等)共性模块,即他们的建立过程是一致的,变化的只是每一个步骤/模块的详细实现细节。这种情景是使用建立者模式的最佳时机,最终产品构建过程是统一且固定的,咱们将变化的部分交给建造者,只须要配置不一样的建造者,就可使一样的构建过程生产出彻底不一样的产品。ui
建造者模式的结构图以下spa
Director:指导者,主要用来使用Buider接口,以一个统一固定的过程生产最终的产品Product设计
Builder:建造者抽象接口,定义建立一个Product对象所需各个部件的操做。在该接口中通常要求包含建立部件的方法如buidPartA,buidPartB等,同时还要包含一个获取最终建立的复杂对象的方法getResult()。builder能够定义为一个抽象类或者接口
ConcreteBuilder:具体的建造者实现,继承自Builder接口,实现接口中定义的建立部件及返回产品的方法。在这里不一样的建立者实现类,对同一部件或步骤进行不一样的详细实现,来完成不一样产品的建立。
Product:最终产品类,表示被建造者构建出来的复杂对象,其用于多个固定的部件或步骤。
咱们以英雄祭坛里造英雄这一过程为例。在使用模式以前,咱们最直接的代码应该像下面这样。
恶魔猎手建立类
/// <summary> /// 恶魔猎手建立类 /// </summary> public class DH { /// <summary> /// 建立英雄 /// </summary> /// <returns></returns> public string BuilderHero() { string body = "黑夜给了我黑色眼睛,我却用它去寻找光明。"; // 建立身体 string weapon = "艾辛诺斯双刃。"; // 建立武器 string mount = "我有这双脚有这双腿。"; // 建立坐骑 return body + weapon + mount; } }
一样,月之女祭司建立类
/// <summary> /// 月之女祭司建立类 /// </summary> public class POM { /// <summary> /// 建立英雄 /// </summary> /// <returns></returns> public string BuilderHero() { string body = "夜幕只为朱颜改,群星陨落无穷。"; // 建立身体 string weapon = "索利达尔·群星之怒。"; // 建立武器 string mount = "艾斯卡达尔。"; // 建立坐骑 return body + weapon + mount; } }
客户调用时只须要实例化不一样的英雄建立类,来完成对应英雄的建立。
DH dh = new DH(); Console.WriteLine(dh.BuilderHero()); POM pom = new POM(); Console.WriteLine(pom.BuilderHero()); Console.ReadLine();
这样咱们须要别的英雄时只须要再添加一个建立该英雄对应的类。
咱们这里只是简单的经过一句话描述建立了英雄身体、武器、坐骑三个关键部位,而实际中一个复杂产品的构件过程是远远要复杂的多,好比咱们常见的文件导出,一个文件有头、内容、尾部说明三类内容,导出txt格式跟导出xml格式的操做,每一个部位的建立都要根据不一样的格式进行处理。
同时咱们发现这样一种状况,每一个英雄建立类中建立英雄的方法其实都是同一种模式,处理步骤彻底同样,惟一变化的部分就在于每一个步骤的具体实现细节,咱们天然会考虑
一、建立每一个英雄都要用到一样的步骤,对与固定不变的部分,咱们要提炼出来,造成统一且公用的处理过程
二、英雄不仅这两个,还会有不少其余英雄须要建立,要求咱们在处理过程不变的状况下,能实现建立不一样英雄的须要
也就是说,咱们的固定不变的处理过程应该和变化的具体实现分离,从而达到固定处理过程的复用,同时还能知足不一样具体实现的需求,此时的需求已经和前面介绍过的建造者模式很是贴近了。
0、提炼具体产品类
将上面用字符串表示的英雄的三个特征使用一个英雄类表示
/// <summary> /// 英雄类 /// </summary> public class Hero { /// <summary> /// 身体特征 /// </summary> public string Body { get; set; } /// <summary> /// 武器 /// </summary> public string Weapon { get; set; } /// <summary> /// 坐骑 /// </summary> public string Mount { get; set; } }
一、建造者接口
建造者接口包含建立各部位的方法定义,及获取最终产品方法的定义
/// <summary> /// 建造者接口 /// </summary> public interface IBuilder { /// <summary> /// 建立身体特征 /// </summary> /// <returns></returns> void BuildBody(); /// <summary> /// 建立武器 /// </summary> /// <returns></returns> void BuildWepon(); /// <summary> /// 建立坐骑 /// </summary> /// <returns></returns> void BuildMount(); /// <summary> /// 获取最终产品 /// </summary> /// <returns></returns> Hero GetResult(); }
二、建造者具体实现类
恶魔猎手建造者实现类
/// <summary> /// 恶魔猎手建造者实现类 /// </summary> public class DHBuilder : IBuilder { private Hero _hero = new Hero(); /// <summary> /// 建立身体特征 /// </summary> /// <returns></returns> public void BuildBody() { _hero.Body = "黑夜给了我黑色眼睛,我却用它去寻找光明。"; } /// <summary> /// 建立武器 /// </summary> /// <returns></returns> public void BuildWeapon() { _hero.Weapon= "艾辛诺斯双刃。"; } /// <summary> /// 建立坐骑 /// </summary> /// <returns></returns> public void BuildMount() { _hero.Mount= "我有这双脚有这双腿。"; } public Hero GetResult() { return _hero; } }
月之女祭司建造者类实现
/// <summary> /// 月之女祭司建造者类 /// </summary> public class POMBuilder : IBuilder { private Hero _hero = new Hero(); /// <summary> /// 建立身体特征 /// </summary> /// <returns></returns> public void BuildBody() { _hero.Body = "夜幕只为朱颜改,群星陨落无穷。"; } /// <summary> /// 建立武器 /// </summary> /// <returns></returns> public void BuildWeapon() { _hero.Weapon = "索利达尔·群星之怒。"; } /// <summary> /// 建立坐骑 /// </summary> /// <returns></returns> public void BuildMount() { _hero.Mount = "艾斯卡达尔。"; } /// <summary> /// 建立最终产品 /// </summary> /// <returns></returns> public Hero GetResult() { return _hero; } }
3 、指导者实现
/// <summary> /// 指导者 /// </summary> public class Director { /// <summary> /// 指导方法 /// </summary> public void Construct(IBuilder builder) { builder.BuildBody(); // 建立身体特征 builder.BuildWeapon(); // 建立武器 builder.BuildMount(); // 建立坐骑 } }
四、客户端调用
Director director = new Director(); DHBuilder buider1 = new DHBuilder(); director.Construct(buider1); Hero dh = buider1.GetResult(); DHBuilder buider2 = new DHBuilder(); director.Construct(buider2); Hero pom = buider1.GetResult();
建造者模式具备一下优势
一、松散耦合
建造者模式把产品的构建过程独立出来,实现产品构建和产品表现的分离,从而使得构建算法能够复用,同时具体产品表现也能够灵活的扩展和切换。
二、能够很容易改变产品内部表示
在建造者模式中,Builder只提供接口给Director使用,具体的部件建立和装配方式有具体的建立者实现类实现,Director不关注具体实现细节,这样一来,若是像改变产品内部的表示,只须要修改具体建造者实现类便可。
三、更好的复用性
固定建造过程能够复用