生成器或者建造者(Builder)模式是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

举个例子,假设我们正在制作一款机甲类的游戏,每个机器人由六个部分组成:头部、身体、左手、右手、左腿和右腿,分为头、身、手和腿四种类型。定义如下:

public interface IHead
{
}public interface IBody
{
}public interface IHand
{
}public interface ILeg
{
}public class Robot
{public IBody Body { get; set;}public IHead Head { get; set;}public IHand LeftHand { get; set;}public IHand RightHand { get; set;}public ILeg LeftLeg { get; set;}public ILeg RightLeg { get; set;}public override string ToString (){return base.ToString ()+ Body.ToString ()+ Head.ToString ()+ LeftHand.ToString ()+ RightHand.ToString ()+ LeftLeg.ToString ()+ RightLeg.ToString ();}
}

我们有不同的(继承自头、身、手、腿接口)部件可以组装机器人,例如:

public class RobotHead : IHead
{
}public class RobotBody : IBody
{
}public class RobotHand : IHand
{
}public class RobotLeg : ILeg
{
}public class CyclopsHead : IHead
{
}public class SolarBody : IBody
{
}public class RazorHand : IHand
{
}public class LaserHand : IHand
{
}public class WheelLeg : ILeg
{
}public class LauncherLeg: ILeg
{
}

例如我需要一个亚当机器人,所有的部件都是最基本的,那么如何组合起来呢?(我来组成头部)

来看看生成器模式,首先创建一个生成器接口:

public interface IRobotBuilder{Robot robot {get;}void CreateHead();void CreateBody();void CreateLeftHand();void CreateRightHand();void CreateLeftLeg ();void CreateRightLeg ();
}

编写亚当的生成器:

public class AdamBuilder : IRobotBuilder{private Robot _robot = new Robot();public Robot robot {get {return _robot;}}public void CreateHead(){_robot.Head = new RobotHead ();}public void CreateBody(){_robot.Body = new RobotBody ();}public void CreateLeftHand(){_robot.LeftHand = new RobotHand ();}public void CreateRightHand(){_robot.RightHand = new RobotHand ();}public void CreateLeftLeg (){_robot.LeftLeg = new RobotLeg ();}public void CreateRightLeg (){_robot.RightLeg = new RobotLeg ();}
}

或者我们需要一个独眼剃刀机器人:

public class CyclopsRazorBuilder : IRobotBuilder
{private Robot _robot = new Robot();public Robot robot {get {return _robot;}}public void CreateHead(){_robot.Head = new CyclopsHead ();}public void CreateBody(){_robot.Body = new RobotBody ();}public void CreateLeftHand(){_robot.LeftHand = new RobotHand ();}public void CreateRightHand(){_robot.RightHand = new RazorHand ();}public void CreateLeftLeg (){_robot.LeftLeg = new RobotLeg ();}public void CreateRightLeg (){_robot.RightLeg = new RobotLeg ();}
}

这样我们就可以调用这两个类来生成不同的机器人了。

但是,每次都调用六个Create方法未免太麻烦了,而且往往我们希望构建过程对用户透明,那么你需要一个Director(策划指挥者):

static public class RobotDirector
{static public Robot Construct(IRobotBuilder rb){rb.CreateHead ();rb.CreateBody ();rb.CreateLeftHand ();rb.CreateRightHand ();rb.CreateLeftLeg ();rb.CreateRightLeg ();return rb.robot;}
}

使用:

Robot adam = RobotDirector.Construct (new AdamBuilder ());

或许你并不希望用户创建builder,那么可以改写成这样:

static public class TRobotDirector
{static public Robot Construct<T>() where T: IRobotBuilder, new(){T rb = new T();rb.CreateHead ();rb.CreateBody ();rb.CreateLeftHand ();rb.CreateRightHand ();rb.CreateLeftLeg ();rb.CreateRightLeg ();return rb.robot;}
}

使用:

Robot cr = TRobotDirector.Construct<CyclopsRazorBuilder> ();

然而,你或许注意到了,每当我们需要一个新的机器人的时候都要新建一个生成器,当不同的部件有千千万(例如喷火的手臂、复眼头部和原子能身体)的时候,又可能会有万万亿的生成器,这样码农可能会累死(给你工资是干啥的,赶紧码起来)。这样也无法动态生成机器人,并且当我们需要增加新类型的组件(例如武器)时,这些万万亿的生成器都需要修改,这显然不合理。

那么,就让我们扔掉所有的生成器吧,使用反射来解决这些问题:

public static class SRobotBuilder
{static private object CreateObjectWithName(string classname){Type type = Type.GetType (classname);return Activator.CreateInstance(type);}static private IHead CreateHead(string cn){return (IHead)CreateObjectWithName (cn);}static private IBody CreateBody(string cn){return (IBody)CreateObjectWithName (cn);}static private IHand CreateLeftHand(string cn){return (IHand)CreateObjectWithName (cn);}static private IHand CreateRightHand(string cn){return (IHand)CreateObjectWithName (cn);}static private ILeg CreateLeftLeg (string cn){return (ILeg)CreateObjectWithName (cn);}static private ILeg CreateRightLeg (string cn){return (ILeg)CreateObjectWithName (cn);}public enum RobotKey{Head,Body,LeftHand,RightHand,LeftLeg,RightLeg,}static public Robot Construct(Dictionary<RobotKey, string> robotDict){Robot robot = new Robot ();robot.Head = CreateHead (robotDict [RobotKey.Head]);robot.Body = CreateBody (robotDict [RobotKey.Body]);robot.LeftHand = CreateLeftHand (robotDict [RobotKey.LeftHand]);robot.RightHand = CreateRightHand (robotDict [RobotKey.RightHand]);robot.LeftLeg = CreateLeftLeg (robotDict [RobotKey.LeftLeg]);robot.RightLeg = CreateRightLeg (robotDict [RobotKey.RightLeg]);return robot;}
}

使用:

     Dictionary<SRobotBuilder.RobotKey,string> robotDict = new Dictionary<SRobotBuilder.RobotKey, string> ();robotDict[SRobotBuilder.RobotKey.Head] = "CyclopsHead";robotDict[SRobotBuilder.RobotKey.Body] = "SolarBody";robotDict[SRobotBuilder.RobotKey.LeftHand] = "RazorHand";robotDict[SRobotBuilder.RobotKey.RightHand] = "LaserHand";robotDict[SRobotBuilder.RobotKey.LeftLeg] = "WheelLeg";robotDict[SRobotBuilder.RobotKey.RightLeg] = "LauncherLeg";Robot nb = SRobotBuilder.Construct (robotDict);

这样我们就可以使用配置文件来生成默认的机器人,而且可以通过运行时生成Dictionary来动态的创建机器人(例如玩家自定义的机器人)。

最后说两句:

生成器模式一般就是用来构建变形金刚用的,如果非要抽象来讲,那么还是变形金刚,就是某个类型由不同的部分组成,而这些部分可以独立变化成不同的子类(例如创建迷宫或者组装赛车,再或者孢子)。

小话设计模式(四)生成器模式相关推荐

  1. 小话设计模式四:策略模式

    策略模式定义: 定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化. 策略模式解析: 策略模式是处理算法的不同变体的一种行为模式,通过在抽 ...

  2. 小话设计模式:Builder模式

    尊重他人的劳动成果,转载请标明出处:http://blog.csdn.net/gengqiquan/article/details/52764455, 本文出自:[gengqiquan的博客] 有一天 ...

  3. 小话设计模式(番外二)委托模式

    委托(Delegate)模式定义了对象之间的一对一的关系,被委托方可以作为委托方的事件接收者或者数据源(Data Source),当它作为事件接受者的时候,可以认为它是一种特殊的观察者(参考小话设计模 ...

  4. 小话设计模式(十)外观模式

    外观(Fascade)模式定义一个高级的接口,将子系统里的一组接口整合起来,提供了一个统一的外观. 在以下情况下可以考虑使用外观模式: (1)设计初期阶段,应该有意识的将不同层分离,层与层之间建立外观 ...

  5. C#软件设计——小话设计模式原则之:依赖倒置原则DIP

    前言:很久之前就想动笔总结下关于软件设计的一些原则,或者说是设计模式的一些原则,奈何被各种bootstrap组件所吸引,一直抽不开身.群里面有朋友问博主是否改行做前端了,呵呵,其实博主是想做" ...

  6. C#设计模式 之 生成器模式

    C#设计模式 之 生成器模式 一,意图 二,动机 三,结构 四,优缺点 五,应用场景 六,代码实现 别名:建造者模式.Builder 一,意图   将一个复杂的对象的构建与其表示相分离,使得同样的构建 ...

  7. 2018.3.31 设计模式之生成器模式详解及例子(对象创建型模式)

    设计模式之生成器模式(对象创建型模式) 1.定义/概念 将一个复杂对象的创建和它的表示分离,使得同样的创建过程可以有不同的表示. 2.生成模式角色 Builder: 生成器接口,定义创建一个Produ ...

  8. C#软件设计——小话设计模式原则之:接口隔离原则ISP

    前言:有朋友问我,设计模式原则这些东西在园子里都讨论烂了,一搜一大把的资料,还花这么大力气去整这个干嘛.博主不得不承认,园子里确实很多这方面的文章,并且不乏出色的博文.博主的想法是,既然要完善知识体系 ...

  9. 设计模式--Builder生成器模式

    GOF<设计模式>中说道:将一个复杂对象的构建与其表示向分离,使得同样的构建过程可以创建不同的表示.    所谓"复杂对象",是指:此对象中还含有其它的子对象.    ...

  10. JAVA23种设计模式之生成器模式

    生成器模式 生成器模式是一种对象的创建模式,可以将一个复杂产品的内部表象和产品的生产过程分隔开来,(构建与表示分离).使得同样的构建过程可以创建不同的表示. 简单的来说,就是讲一个复杂的对象拆分成一个 ...

最新文章

  1. [七月挑选]使用idea创建spring boot 项目
  2. Yii CDbCriteria 常用方法
  3. matlab中矩阵的累加,累加和与累乘积在matlab中-read.ppt
  4. python中的捕获异常、异常跟踪
  5. 怎么修改CSDN上传图片水印的字体大小?(去水印)
  6. JZOJ 4933. 【NOIP2017提高组模拟12.24】C
  7. Linux进程 管理,Linux进程查看与管理以及作业控制
  8. ubuntu Linux18.10/19.10下的护眼宝
  9. 硬件:实用的电脑维护小常识
  10. 把 charles,Fiddler 证书安装到安卓根目录,解决安卓微信 7.0 版本以后安装证书也无法抓包问题,需要 root
  11. ajax与DOM的使用,AJAX和DOM的运行经验
  12. redis下key的过期时间详解
  13. Python脚本实现单据体背景色及字段前景色设置
  14. 技术升级成为Linux运维人前途的魔障,是跟进还是选择被淘汰?
  15. 学刘红杰老师博客营销,知如何提高博客访问流量
  16. linux python2.7安装pip_linux安装pip2.7
  17. 自己制作深度学习数据集教程
  18. 通俗科普:弦论要求空间必须是25维的解释
  19. 技术概况python_《技》字意思读音、组词解释及笔画数 - 新华字典 - 911查询
  20. html如何注释文字,css怎么注释?

热门文章

  1. 鼠标自动移动 防止锁屏睡眠
  2. 人工智能导论(专家系统)
  3. UAV021(六):系统架构优化、SBUS协议、遥控器控制电机转动
  4. linux vi命令的查询,linux vi命令模式详解
  5. 华为手机服务器位置,华为手机怎么查看云服务器地址
  6. 批量自动付款(京东)
  7. 人工智能 一种现代方法 第7章 逻辑Agent(命题逻辑)
  8. mtk camera faq
  9. 【君思智慧园区】智慧园区建设规划方案
  10. 计算机WPS一级教材PDF,2017年计算机一级WPS辅导:金山词霸PDF文档取词攻略