【设计模式 - 3】之建造者模式(Builder)
1、模式简介
建造者模式也叫生成器模式,和抽象工厂模式相似,也是一种构建复杂对象的模式。
建造者模式中的角色分类:
- 抽象建造者Builder:接口类型,用于规范各个产品的组成部分;
- 具体建造者ConcreteBuilder:实现Builder中的所有方法,并且返回一个构造好的产品实例;
- 指导者Director:根据用户的需求安排产品各组件的生产顺序,然后告诉具体建造者开始建造;
- 产品Product:用户最终看到的复杂对象。
各组成部分之间的UML框架如下图所示:
2、代码
项目框架如下图所示:
产品的组成部分Part父类中的代码:
public class Part {
private String name; protected void setName(String name) {
this.name = name;
} public void onPartPrepared() {
System.out.println(this.name + "prepared......");
}
}
Part的子类PartA中的代码:
public class PartA extends Part {
public PartA() {
super.setName("PartA");
}
}
产品类Product中的代码:
public class Product {
private List<Part> parts; public Product() {
this.parts = new ArrayList<>();
} public void addComponent(Part part) {
parts.add(part);
} public void display() {
for (Part p : parts) {
p.onPartPrepared();
}
System.out.println();
}
}
建造者的父类Builder中的代码:
public abstract class Builder {
protected Product product; public abstract Product buildProduct();
}
Builder的子类ProductBuilder1中的代码:
public class ProductBuilder1 extendsBuilder { @Override
public Product buildProduct() {
super.product = new Product();
super.product.addComponent(new PartA());
super.product.addComponent(new PartB());
super.product.addComponent(new PartD());
return super.product;
}
}
指导者Director中的代码:
public class Director {
private String name;
private Builder builder; public Director(String name, Builder builder) {
this.name = name;
this.builder = builder;
} public void constructComponent() {
System.out.println("Preparing Components For " + name);
Productproduct = builder.buildProduct();
product.display();
}
}
测试类Test中的代码:
public class Test {
public static void main(String[] args) {
Directordirector1 = new Director("Product 01", new ProductBuilder1());
director1.constructComponent(); Directordirector2 = new Director("Product 02", new ProductBuilder2());
director2.constructComponent(); Directordirector3 = new Director("Product 03", new ProductBuilder3());
director3.constructComponent();
}
}
运行结果如下图所示:
3、总结
符合以下要求的对象可以使用建造者模式来创建:
- 需要创建的对象是一个组合结构;
- 需要创建的对象的创建过程不必被用户知道;
- 允许对象通过多个步骤来创建,并且可以改变过程。
建造者模式的优点:
- 封装了对象创建的具体代码;
- 可以更加精细的控制对象的构造过程;
- 将对象的创建过程与创建该对象的类解耦,提高了灵活性;
- 指挥者的代码不需要修改,符合“开闭原则”。
建造者模式的缺点:
每种对象的创建以及同一种对象的不同方式的创建都需要一个单独的具体建造者类。
建造者模式与抽象工厂模式的区别:
- 建造者模式构建对象是一步一步完成的,关注的是各零件的工艺顺序;而抽象工厂模式将一个系列的产品看作一个整体,即将这个系列的产品的构造封装成一个方法,最终直接返回产品;
- 抽象工厂模式中用户是直接与工厂交互的,通过将用户需求传达给工厂直接生产产品;而建造者模式中用户是与指导者交互的,由指导者与建造者交流生产产品。
从上面的区别可以看出,建造者模式适合生产的产品复杂度比抽象工厂模式适合生产的产品的复杂度要高。
最后贴出建造者模式的GitHub地址:【GitHub - Builder】。
【设计模式 - 3】之建造者模式(Builder)的更多相关文章
- 【原】iOS设计模式之:建造者模式Builder Pattern,用于改进初始化参数
本文主要讨论一下iOS中的Builder Pattern.与网上很多版本不同,本文不去长篇大论地解释建造者模式的概念,那些东西太虚了.设计模式这种东西是为了解决实际问题的,不能为了设计模式而设计模式, ...
- iOS设计模式之:建造者模式Builder Pattern,用于改进初始化参数
转自:http://www.cnblogs.com/wengzilin/p/4365855.html 本文主要讨论一下iOS中的Builder Pattern.与网上很多版本不同,本文不去长篇大论地解 ...
- 设计模式系列之建造者模式(Builder Pattern)——复杂对象的组装与创建
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
- IOS设计模式浅析之建造者模式(Builder)
定义 "将一个复杂对象的构建与它的表现分离,使得同样的构建过程可以创建不同的表现". 最初的定义出现于<设计模式>(Addison-Wesley,1994). 看这个概 ...
- Net设计模式实例之建造者模式(Builder Pattern)
一.建造者模式简介(Brief Introduction) 建造者模式(Builder Pattern),将一个复杂对象的构建与它的表示分离,使的同样的构建过程可以创建不同的表示. 建造者模式的优点是 ...
- 设计模式 笔记 生成器(建造者)模式 Builder
//---------------------------15/04/08---------------------------- //builder 生成器(建造者)模式---对象创建型模式 /* ...
- 设计模式学习之建造者模式(Builder,创建型模式)(6)
假如我们需要建造一个房子,并且我们也不知道如何去建造房子,所以就去找别人帮我们造房子 第一步: 新建一个房子类House,里面有房子该有的属性,我们去找房子建造者接口HouseBuilder,我们要建 ...
- 乐在其中设计模式(C#) - 建造者模式(Builder Pattern)
原文:乐在其中设计模式(C#) - 建造者模式(Builder Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 建造者模式(Builder Pattern) 作者:webabc ...
- 【设计模式】建造者模式 Builder Pattern
前面学习了简单工厂模式,工厂方法模式以及抽象工厂模式,这些都是创建类的对象所使用的一些常用的方法和套路, 那么如果我们创建一个很复杂的对象可上面的三种方法都不太适合,那么“专业的事交给专业人去做”,2 ...
- 设计模式-05建造者模式(Builder Pattern)
1.模式动机 比如我们要组装一台电脑,都知道电脑是由 CPU.主板.内存.硬盘.显卡.机箱.显示器.键盘和鼠标组成,其中非常重要的一点就是这些硬件都是可以灵活选择,但是组装步骤都是大同小异(可以组一个 ...
随机推荐
- CentOS 7.0 重置root密码
步骤一,开机时随便按下键盘,进入以下菜单 步骤二: 选择第一项,按e键进行修改 步骤三,定位到 ro( linux 16 or linuxefi ) 步骤四:把ro改成 “rw init=/sysro ...
- tupian
http://www.iconfont.cn/https://icons8.com/http://ico.58pic.com/http://www.easyicon.net/
- angularJS的controller之间如何正确的通信
AngularJS中的controller是个函数,用来向视图的作用域($scope)添加额外的功能,我们用它来给作用域对象设置初始状态,并添加自定义行为. 当我们在创建新的控制器时,angularJ ...
- cmd 窗口的复制粘贴
如下几种方法1.点击鼠标右键,选择标志,再点击左键拖动选择要复制的内容,然后回车即可复制被 选择的内容 2.点击鼠标右键,选择标志,再点击左键拖动选择要复制的内容,然后点击鼠标右键, 此时就把选择的内 ...
- 对c++服务端进行覆盖率统计
(1)首先需要为每个被测程序的所有编译文件增加选项,如果文件太多,这无疑是灾难,可利用spec文件达到目的 sed -i '$ a\export LD_PRELOAD=/usr/local/bin/c ...
- 各大Oj平台介绍[转]
1.题库与网站资源题库-在线提交系统(Online Judge)简介 下面是几个比较大的在线提交系统(OnlineJudge)里面有大量历年的竞赛题目,注册一个ID,然后用自己熟悉的语言(一般有P ...
- bzoj 1191: [HNOI2006]超级英雄Hero 并查集 || 匈牙利算法
1191: [HNOI2006]超级英雄Hero Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1804 Solved: 850[Submit][S ...
- C语言头文件的作用
C99中规定, 所有顶层的默认存储类标志符都是extern ! 头文件中声明的函数,默认都是extern前缀.但是为了我们程序员方便,我们采取下面的手段: 我个人认为是extern催生了头文件的诞生. ...
- RESTful, 说说 http 的 patch method
最早的时候,我们只需要 GET 和 POST 方法,POST 方法的引入也只是为了消除 URL 过长,参数隐藏,上传文件的问题,完全和语义无关.接触到 RESTful 之后,我们开始思考 GET 和 ...
- js对ajax返回数组的处理
引言: ajax异步传输,可以传输字符串,但是数组这样的数据,就不太好传递了,这个时候怎么办呢? 答案是可以通过json来处理,后台将数据数据进行json编码! 然后客户端,通过js来进行解析. 这样 ...