建造者模式(Builder)-宏观的使用角度
建造者模式(Builder)
建造者模式是用来解决产品对象的创建过程是由多个零件组成的情况,这些零件与产品本身是组合关系,也就是部分与整体,这些零件的创建顺序,还有一些创建中的逻辑,都是稳定的,可以封装起来的.
例如,一个邮件对象,要成功的使用前,需要设置主题,收件人,发件人,正文,附件等零件,这些零件都与邮件对象是组合关系,如果将这些创建逻辑散落在调用处,每次使用邮件对象时都要进行繁琐的装配零件工作,而且还有可能会有一定的业务逻辑掺在这其中.
建造者模式除了将构建产品零件的算法封装起来,还可以支持消费的产品对象的动态选择,当然这也是面向对象不变的话题,封装变化点,依赖倒置.具体产品是一个对象还是一系列,这个根据实际的业务设计有所不同.

在上图中展示了一个基础的建造者模式的结构,为了尽量说明实际情况的模式环境,我们这里描绘了一个系列的产品对象.红色字体部分代表的是实现层,也就是依赖倒置原则中所讲的,不依赖实现,而依赖抽象.这里的实现层在系统中肯定是频繁变化的,而且可以随时以扩展的方式改变功能(开闭原则),而蓝色表示的是系统中的抽象层,要求是稳定的,不太能够应对频繁的功能变化.
产品对象
先从产品类来讲起,这一块通常是核心的业务骨架,对于一组产品对象,现实系统中肯定比这里的结构还要复杂,读者视自身业务情况来设计,在上图中,Product代表的是抽象产品接口,这个接口描述依赖着ProductPart,ProductPart2两个抽象的零件.这之间的关系是组合关系,换言之,就是Product的生成是需要先创建ProductPart与ProductPart2两个零件.具体的实现零件则是ConcretePart与ConcretePart2两个类来完成. ConecreteProduct是产品的具体实现类.
可以看出,红色部分的几个Conecrete开头的类,都是可以应对系统变化的,也就是我们随时可以加入ConecretePratXX 或者 ConecreteProductXXX这样的新的实现来丰富我们的系统.
封装产品的创建过程
在介绍完上边的产品结构之后,我们应该了解到Product是依赖着ProductPart与ProductPart2这两个零件的,建造者模式要封装的是这个对象的创建过程,比如:先创建Part1再创建part2,或者说part2的必须是10个以上.这就是对创建算法的封装.
Builder是抽象的建造者,其中描述buildPart()与buildPart2()两个方法分别构建不同的零件.getProduct()返回最终的产品对象Product.
ConcreteBuilder是具体的构建实现,这里与ConcretePart,ConcretePart2两个具体零件对象是关联着的,如果加入新的一套不同风格的零件,则也相应的要增加XXXConcreteBuilder,当然,如果我们很确定系统只有一种风格,那大哥不必将Builder抽象化.
Director是一个导演类,用为将具体稳定的创建算法封装在这里,比如刚才所讲的,要求创建10个Part2对象.
最后我们来看Client类,这里是指代码调用处,依赖着产品的抽象层,完全不关心具体层,在调用时只需要选择不同的ConcreteBuilder就可以完成不同风格产品的组装过程.值得说明的一点,风格是指加入不同的实现类,比如再加一套新风格,就需要加入新的派生自Product , ProductPart , ProductPart2 ,Builder的几个实现类.
具体举例说明
写到这里,也不免俗套的要举一个其实和实际开发相距甚远,还有些套路化的例子了,虽然园子里关于设计模式的文章如汗牛充栋,也有很多口号讲,不要重复搞轮子.但小弟还是认为,搞轮子和写这些文章对个人的提高是很大的,同时也能在过程中得到与别人的互动交流,设计模式本来就还有一层意思,那就是交流.我们大家都约定俗成,交流起来就更方便了不是吗,好了,各们大哥,我可以开始了吗?
假如我们有一个游戏场景,需要一个房屋,这个房屋由多面墙壁,一块地板,一块天花板组成.我们很自然的可以写出房屋,墙壁,地板,天花板对象,而且房屋与其它对象是组合关系,表现在代码中应该就是成员变量.
由于系统要求房屋有着不同的风格,比如一款普通风格,另一款精致风格.这时我们很自然的应该将房屋,地板,天花板,墙壁都抽象化.这些对象就对应前面所讲的产品结构.
package com.j2kaka.coolka.examples.pattern.builder;
/**
* 抽象房顶
*
* @author aladdinty
* @create 2018-01-10
**/
public abstract class AbsRoof
{
public abstract String getRoofInfo() ;
}
package com.j2kaka.coolka.examples.pattern.builder;
/**
* 抽象墙壁
*
* @author aladdinty
* @create 2018-01-10
**/
public abstract class AbsWall
{
public abstract String getWallInfo() ;
}
package com.j2kaka.coolka.examples.pattern.builder;
/**
* 抽象地板
*
* @author aladdinty
* @create 2018-01-10
**/
public abstract class AbsFloor
{
public abstract String getFloorInfo() ;
}
package com.j2kaka.coolka.examples.pattern.builder;
import java.util.ArrayList;
import java.util.List;
/**
* 抽象的房子类
* @author aladdinty
* @create 2018-01-10
**/
public abstract class AbsHouse
{
private List<AbsWall> wallList ;
private AbsFloor floor ;
private AbsRoof roof ;
/**添加墙壁*/
public void addWall (AbsWall wall)
{
if( this.wallList == null )
{
this.wallList = new ArrayList<AbsWall> () ;
}
this.wallList.add ( wall ) ;
}
/**设置地板*/
public void setFloor( AbsFloor floor )
{
this.floor = floor ;
}
/**设置天花板*/
public void setRoof( AbsRoof roof )
{
this.roof = roof ;
}
/**获取天花板*/
public AbsRoof getRoof ()
{
return roof;
}
/**获取地板*/
public AbsFloor getFloor ()
{
return floor;
}
/**获取所有墙壁*/
public List<AbsWall> getAllWall ()
{
return wallList;
}
public String getInfo()
{
StringBuffer sb = new StringBuffer () ;
for( AbsWall wall : this.wallList )
{
sb.append ( wall.getWallInfo () + "|") ;
}
return "房子的配置是这样的:" + "有几面墙:" + wallList.size () + "->" + sb.toString () + "->"+this.roof.getRoofInfo () +"->" + this.floor.getFloorInfo () ;
}
}
好抽象层的产品描述完成了,具体产品要有对应的实现了,这里分别提供普通款与精致款风格的不同实现.
package com.j2kaka.coolka.examples.pattern.builder;
/**
* 普通地板
*
* @author aladdinty
* @create 2018-01-10
**/
public class CommonFloor extends AbsFloor
{
@Override
public String getFloorInfo ()
{
return "普通地板";
}
}
package com.j2kaka.coolka.examples.pattern.builder;
/**
* 普通天花板
*
* @author aladdinty
* @create 2018-01-10
**/
public class CommonRoof extends AbsRoof
{
@Override
public String getRoofInfo ()
{
return "普通天花板";
}
}
package com.j2kaka.coolka.examples.pattern.builder;
/**
* 普通风格的墙面
*
* @author aladdinty
* @create 2018-01-10
**/
public class CommonWall extends AbsWall
{
@Override
public String getWallInfo ()
{
return "普通墙面";
}
}
package com.j2kaka.coolka.examples.pattern.builder;
import java.util.ArrayList;
import java.util.List;
/**
* 普通房子风格实现
*
* @author aladdinty
* @create 2018-01-10
**/
public class CommonHouseImpl extends AbsHouse
{
}
再来一款精致款式实现
package com.j2kaka.coolka.examples.pattern.builder;
/**
* 精致地板
*
* @author aladdinty
* @create 2018-01-10
**/
public class FinesseFloor extends AbsFloor
{
@Override
public String getFloorInfo ()
{
return "精致地板";
}
}
package com.j2kaka.coolka.examples.pattern.builder;
/**
* 精致天花板
*
* @author aladdinty
* @create 2018-01-10
**/
public class FinesseRoof extends AbsRoof
{
@Override
public String getRoofInfo ()
{
return "精致天花板";
}
}
package com.j2kaka.coolka.examples.pattern.builder;
/**
* 精致的的墙面
*
* @author aladdinty
* @create 2018-01-10
**/
public class FinesseWall extends AbsWall
{
@Override
public String getWallInfo ()
{
return "精致墙面";
}
}
package com.j2kaka.coolka.examples.pattern.builder;
/**
* 精致风格实现
*
* @author aladdinty
* @create 2018-01-10
**/
public class FinesseHouseImpl extends AbsHouse
{
}
现目前为止,我们实现了产品的抽象化,不过还没体现出建造者模式的核心,我们开头就说过,要封装的是建造过程,同时可以动态选择产品的不同实现.让客户端毫不知情,下面代码中抽象的构建器描述我们的产品创建过程中用到的动作.最后要求返回房屋对象.
package com.j2kaka.coolka.examples.pattern.builder;
/**
* 抽象建造者
*
* @author aladdinty
* @create 2018-01-10
**/
public abstract class AbsBuilder
{
public abstract void buildFloor() ;
public abstract void buildRoof() ;
public abstract void buildWall() ;
public abstract AbsHouse getHouse() ;
}
具体实现不同的构建器,因为我们这个举例中有2套风格,分别是普通与精致风格,产品结构也有了相应的抽象体现,所以Builder的实现也是一一对应的.在这两个具体实现类里边,都是直接关联了具体的对象产品.
package com.j2kaka.coolka.examples.pattern.builder;
/**
* 普通风格的构建器实现
*
* @author aladdinty
* @create 2018-01-10
**/
public class CommonBuilderImpl extends AbsBuilder
{
private AbsHouse house = new CommonHouseImpl () ;
@Override
public void buildFloor ()
{
house.setFloor ( new CommonFloor ());
}
@Override
public void buildRoof ()
{
house.setRoof ( new CommonRoof ());
}
@Override
public void buildWall ()
{
house.addWall ( new CommonWall () );
}
@Override
public AbsHouse getHouse ()
{
return this.house;
}
}
package com.j2kaka.coolka.examples.pattern.builder;
/**
* 精致风格房屋构建器实现
*
* @author aladdinty
* @create 2018-01-10
**/
public class FinesseBuilderImpl extends AbsBuilder
{
private AbsHouse house = new FinesseHouseImpl () ;
@Override
public void buildFloor ()
{
house.setFloor ( new FinesseFloor ());
}
@Override
public void buildRoof ()
{
house.setRoof ( new FinesseRoof ());
}
@Override
public void buildWall ()
{
house.addWall ( new FinesseWall () );
}
@Override
public AbsHouse getHouse ()
{
return this.house;
}
}
好了,构建器完成了,产品对象也完成了,现在到我们的工头出场了,他一声令下,给我盖..这里的工具其实是对应之前结构中的Director类,将稳定的对象结构创建步骤和算法封装起来,我们这里简单要求,要有4面墙壁,还有一个地板和一个天花板.
```package com.j2kaka.coolka.examples.pattern.builder;
/**
- 工队领头人
- 这个类中代表的是稳定的构建算法,是不能适应频繁变化的.
- @author aladdinty
@create 2018-01-10
**/
public class Foreman
{
public static AbsHouse createMyHouse( AbsBuilder builder )
{//先盖地板 builder.buildFloor (); //接着修建四面墙壁 for (int i = 0; i < 4; i++) { builder.buildWall (); } //把房顶盖上.. builder.buildRoof (); return builder.getHouse () ;}
}
最后我们看看调用处
package com.j2kaka.coolka.examples.pattern.builder;
/**
- 调用处代码
- @author aladdinty
@create 2018-01-10
**/
public class Client
{
public static void main(String[] args )
{
AbsHouse house = Foreman.createMyHouse ( new FinesseBuilderImpl () ) ;
System.out.println ( house.getInfo ());AbsHouse house2 = Foreman.createMyHouse ( new CommonBuilderImpl () ) ; System.out.println ( house2.getInfo ());}
}
```
其实忙活了半天,只是为调用处以后可以应对变化时不做调整,变化全部封在了后面的结构中.在这里只需要知道产品的抽象接口,调用工头类,决定使用哪种风格的构建器就可以了.

好了,欢乐时光总是过的特别快,感谢您能看到这里,希望我的付出可以给您带来一点点的帮助,如果不爽请轻虐,如果疑问欢迎留言交流
建造者模式(Builder)-宏观的使用角度的更多相关文章
- 【原】iOS设计模式之:建造者模式Builder Pattern,用于改进初始化参数
本文主要讨论一下iOS中的Builder Pattern.与网上很多版本不同,本文不去长篇大论地解释建造者模式的概念,那些东西太虚了.设计模式这种东西是为了解决实际问题的,不能为了设计模式而设计模式, ...
- iOS设计模式之:建造者模式Builder Pattern,用于改进初始化参数
转自:http://www.cnblogs.com/wengzilin/p/4365855.html 本文主要讨论一下iOS中的Builder Pattern.与网上很多版本不同,本文不去长篇大论地解 ...
- 乐在其中设计模式(C#) - 建造者模式(Builder Pattern)
原文:乐在其中设计模式(C#) - 建造者模式(Builder Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 建造者模式(Builder Pattern) 作者:webabc ...
- 【设计模式】建造者模式 Builder Pattern
前面学习了简单工厂模式,工厂方法模式以及抽象工厂模式,这些都是创建类的对象所使用的一些常用的方法和套路, 那么如果我们创建一个很复杂的对象可上面的三种方法都不太适合,那么“专业的事交给专业人去做”,2 ...
- 建造者模式(Builder Pattern)
建造者模式(Builder Pattern) 它可以将多个简单的对象一步一步构建成一个复杂的对象. 意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示. 主要解决:主要解决在软 ...
- 二十四种设计模式:建造者模式(Builder Pattern)
建造者模式(Builder Pattern) 介绍将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 示例用同样的构建过程创建Sql和Xml的Insert()方法和Get()方 ...
- 建造者模式(Builder)——从组装电脑开始
建造者模式(Builder)--从组装电脑开始 建造者模式概括起来就是将不同独立的组件按照一定的条件组合起来构成一个相对业务完整的对象.调用者无需知道构造的过程. 我们从组装电脑开始 让我们从买组装电 ...
- 设计模式—建造者模式(Builder)
title: 设计模式-建造者模式 建造者模式(Builder)是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节.建造者模式属于对 ...
- 设计模式系列之建造者模式(Builder Pattern)——复杂对象的组装与创建
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
随机推荐
- 》》stroll--各种特效下拉菜单
<!doctype html> <html lang="en"> <head> <meta charset="utf-8&quo ...
- C++ - 复制容器(container)的元素至还有一个容器
复制容器(container)的元素至还有一个容器 本文地址: http://blog.csdn.net/caroline_wendy C++复制容器(container)元素, 能够使用标准库(ST ...
- bzoj1513【POI2006】Tet-Tetris 3D
1513: [POI2006]Tet-Tetris 3D Time Limit: 30 Sec Memory Limit: 162 MB Submit: 733 Solved: 245 [Subm ...
- webpack+babel项目在IE下报Promise未定义错误引出的思考
低版本浏览器引起的问题 最近开发一个基于webpack+babel+react的项目,一般本地是在chrome浏览上面开发,chrome浏览器开发因为支持大部分新的js特性,所以一般不怎么需要poly ...
- @Autowired注解在抽象类中实效的原因分析
最近在工作中遇到这个问题,在抽象类中使用Autowired这个注解,注入mybatis的dao时,总是出现空指针异常,通过日志的打印,发现是这个dao注入失败为空.然后通过new出spring上下文对 ...
- Python网络爬虫与信息提取(二)—— BeautifulSoup
BeautifulSoup官方介绍: Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式. 官方 ...
- #ifdef #else #endif #if #ifndef 的用法
预编译就是在对源文件进行处理之前(如在语法扫描和分析之前),先处理预处理部分,精简代码,然后再进行编译. 预处理命令有:#include 文件包含.#define 宏定义.以及要重点讲的#if.#if ...
- IOS学习2——Xcode快捷键大全
转载自:图文解释XCode常用快捷键的使用 刚开始用Xcode是不是发现以前熟悉的开发环境的快捷键都不能用了?怎么快捷运行,停止,编辑等等.都不一样了.快速的掌握这些快捷键,能提供开发的效率. 其实快 ...
- NOIP2017day1游记
NOIP 2017总结 Day1 Day1T1 第一眼看到瞬间慌掉,woc这玩意啥! 然后懵逼了两分钟 好的 我相信他是NOIP第一题 那我就打个表吧 然后花五分钟打了个暴力 玩了几组数据 哇!好像有 ...
- BZOJ4817 SDOI2017 相关分析
4821: [Sdoi2017]相关分析 Time Limit: 10 Sec Memory Limit: 128 MBSec Special Judge Description Frank对天文 ...