参考

1. Builder Design Pattern | Youtube

2. 建造者模式(Builder和Director)| 博客园

3. 深入理解Builder模式 | 简书

建造者模式(Builder Pattern)

将一个复杂对象的构建与表示分离,使得同样的构建过程可以不同的表示。

通常,在建造者Builder中包含多个不同的属性(基本类型或者别的类对象),这些属性由Builder的方法构建,由Director来组装出一种产品Product。 也就是说,Builder Pattern的目的是为了构建一个或多个Product,不同的构建过程可以表示不同Product。每一个Builder至少代表了一种不同属性的组合,以组装成产品。

组成

Builder 为创建一个Product对象的各个部件指定的抽象接口
ConcreteBuilder 

实现Builder接口,构造和装配Product产品的各个部件;

定义并明确所创建的表示;

提供一个获取Product的接口。

Director 构造一个使用Builder接口对象
Product

被构造的复杂对象;

由ConcreteBuilder内部表示和定义它的装配过程;

包含了组成部件/属性的类,包括将这些部件装配成最终产品的接口。

适用场景

[参考1~2]:建造者模式用于创建的Product对象,由其他多个对象组成。

1)当你想建造的对象由其他对象(称为部件)组成;

2)当你想这些组件的创建独立于主要对象;

3)隐藏来自client的部分的创建,以至于这部分和创建对象是相互独立的;

4)建造者知道细节,并且别人不知道;

通俗讲,当自己想创建的对象由多个其他类对象组成,并且希望自己创建的对象独立于其他对象的创建,用户不必知道创建这个对象的细节,只需要指定特定Builder来负责建造组件、Director负责何时组装以及如何组装即可。

特点

1) 分步构建一个复杂对象。Product通常由别的多个不同的子对象组成,builder提供构建接口和获取最终产品对象的接口。

2) 支持多种构建表示。Builder模式封装了构建的过程,用户只需传入关心的参数和必须的参数,而不用关心复杂的构建过程,就能创建出不同的表示。

3) 将部件的创建和部件的组装方式解耦,部件类型和部件装配方式互不影响。

缺点

1) 不适合包含同类别子对象的Product创建,如组合模式;

2) 当Product增加部件时,可能会导致Builder及其子类, Director的大量修改;

与工厂模式,抽象工厂比较

工厂模式:提供统一的抽象接口,让子类决定实例化哪一个类,使对象的初始化延迟到子类进行。

抽象工厂:为创建一组相关或者相互依赖的对象提供一个接口,而无需指定他们具体的类。

1. 建造者 vs 工厂模式

工厂模式通常只生产一种产品,而且产品之间没有必然联系。侧重于表示接口和Product之间的关系。

建造者模式可以产生一种或多种产品表示,不同的构建过程可以表示不同Product。侧重于用多个部件构建复杂产品表示的过程。

2. 建造者 vs 抽象工厂

抽象工厂往往产出多个Product,并且Product之间存在一定关联或依赖关系。每个具体Product要求用工厂来创建。抽象工厂的具体工厂生产产品,可以用Builder模式来创建。侧重于表示一组方案。

建造者模式通常产生1个产品,不同的构建过程有不同的Product表示。侧重于表示1个复杂产品的构建的过程。

通用类图

 Figure1 Builder Pattern通用类图

demo

下面这个例程跟网上流传的“造人”"造船"例程很像,能体现Builder模式的基本特点,“将对象的创建与表示分离”。但是有一个缺点,就是一个Builder只能生产一种产品对象,因为产品组件在Builder中的创建已经固化了,当需要添加一种对象时,就需要添加一种Builder。

[参考1] Client要创建Robot,就需要通过RobotBuilder创建OldStyleRobotBuilder,然后再创建RobotEngineer(Robot工程师),在RobotEngineer通过RobotPlan(Robot设计)创建Robot对象。创建过程如Figure2.

Figure2 Client创建Robot过程

 

Figure3 demo的UML类图

代码

1. 创建Robot接口RobotPlan,定义各属性设置的公共方法

RoboPlan.java

public interface RobotPlan {

    public void setHead(String head);

    public void setTorso(String torso);

    public void setArms(String arms);

    public void setLegs(String legs);
}

2.定义Robot,实现RobotPlan接口,这里的几个属性用String类型

Robot.java

public class Robot implements RobotPlan {
private String head;
private String torso;
private String arms;
private String legs; @Override
public void setHead(String head) { this.head = head; } public String getHead() { return head; } @Override
public void setTorso(String torso) { this.torso = torso; } public String getTorso() { return torso; } @Override
public void setArms(String arms) { this.arms = arms; } public String getArms() { return arms; } @Override
public void setLegs(String legs) { this.legs = legs; } public String getLegs() { return legs; }
}

3.定义Robot的Builder 接口RobotBuilder,声明构建Robot子对象/属性的公共方法,读取Robot的方法

RobotBuilder.java

public interface RobotBuilder {

    public void buildHead();

    public void buildTorso();

    public void buildArms();

    public void buildLegs();

    public Robot getRobot();
}

4.定义OldStyleRobotBuilder,实现接口RobotBuilder,负责具体构建Robot的子对象/属性

OldStyleRobotBuilder.java

/* 将robot各子部件固化到builder中 */
public class OldStyleRobotBuilder implements RobotBuilder { private Robot robot; public OldStyleRobotBuilder(){
robot = new Robot();
} @Override
public void buildHead() {
robot.setHead("Tin Head");
} @Override
public void buildTorso() {
robot.setTorso("Tin Torso");
} @Override
public void buildArms() {
robot.setArms("Blowtorch Arms");
} @Override
public void buildLegs() {
robot.setLegs("Roller Legs");
} @Override
public Robot getRobot() {
return robot;
} }

5. 定义Director RobotEngineer,指导RobotBuilder构建Robot

RobotEngineer.java

/* 指导RobotBuilder构建Robot*/
public class RobotEngineer {
private RobotBuilder robotBuilder; public RobotEngineer (RobotBuilder robotBuilder){
this.robotBuilder = robotBuilder;
} public void makeRobot(){
robotBuilder.buildHead();
robotBuilder.buildTorso();
robotBuilder.buildArms();
robotBuilder.buildLegs(); // 另外一种方式是在此处创建Robot, 然后将build构建的结果复制给Robot
} public Robot getRobot(){
return robotBuilder.getRobot();
}
}

6. RobotBuilderDemo(Client)测试例程

1) 第一步是创建RobotBuilder具体对象

2) 第二步是创建Director RobotEngineer,用于指导构建Robot

3) 第三步是制造/组装Robot

4) 第四步是测试组装的Robot属性

public class RobotBuilderDemo {

    public static void main(String[] args){
RobotBuilder robotBuilder = new OldStyleRobotBuilder();
RobotEngineer robotEngineer = new RobotEngineer(robotBuilder);
robotEngineer.makeRobot(); Robot robot = robotEngineer.getRobot();
System.out.println("Robot build component:");
System.out.println("Robot Head: "+robot.getHead());
System.out.println("Robot Torso: "+robot.getTorso());
System.out.println("Robot Arms:"+robot.getArms());
System.out.println("Robot Legs:"+robot.getLegs());
}
}

7. 运行结果

总结

1. 产品的参数往往由外部Client来决定,因此可以将Builder中构建Product属性的方法设为由外部参数决定。

例如,public void buildHead(); 可修改为public void buildHead(String head)

设计模式01 创建型模式 - 建造者模式(Build Pattern)的更多相关文章

  1. 设计模式01 创建型模式 - 单例模式(Singleton Pattern)

    参考 [1] 设计模式之:创建型设计模式(6种) | 博客园 [2] 单例模式的八种写法比较 | 博客园 单例模式(Singleton  Pattern) 确保一个类有且仅有一个实例,并且为客户提供一 ...

  2. 设计模式01 创建型模式 - 原型模式(Protype Pattern)

    参考 1. 设计模式:原型模式 | 博客园 2. Java clone深拷贝.浅拷贝 | CSDN 3. Cloneable接口和Object的clone()方法 | 博客园 原型模式(Prototy ...

  3. 设计模式学习-使用go实现建造者模式

    建造者模式 定义 适用范围 与工厂模式的区别 优点 缺点 参考 建造者模式 定义 Builder 模式,中文翻译为建造者模式或者构建者模式,也有人叫它生成器模式. 建造者模式(Builder Patt ...

  4. js常用设计模式实现(三)建造者模式

    创建型模式 创建型模式是对一个类的实例化过程进行了抽象,把对象的创建和对象的使用进行了分离 关于创建型模式,已经接近尾声了,还剩下建造者模式和原型模式,这一篇说一说建造者模式 建造者模式的定义 将一个 ...

  5. java设计模式(二)单例模式 建造者模式

    (三)单例模式 单例模式应该是最常见的设计模式,作用是保证在JVM中,该对象仅仅有一个实例存在. 长处:1.降低某些创建比較频繁的或者比較大型的对象的系统开销. 2.省去了new操作符,减少系统内存使 ...

  6. 设计模式之第11章-建造者模式(Java实现)

    设计模式之第11章-建造者模式(Java实现) “那个餐厅我也是醉了...”“怎么了?”“上菜顺序啊,竟然先上甜品,然后是冷饮,再然后才是菜什么的,无语死了.”“这个顺序也有人这么点的啊.不过很少就是 ...

  7. Java设计模式(四)Builder建造者模式

    一.场景描述 建造者模式同工厂模式.抽象工厂模式一样,用于创建继承类对象. 工厂模式:http://www.cnblogs.com/mahongbiao/p/8618970.html 抽象工厂模式:h ...

  8. (转自精通Python设计模式)Python设计模式之创建型模式——2.建造者模式

    建造者模式将一个复杂对象的构造过程与其表现分离,这样,同一个构造过程可用于创建多个不同的表现. 我们来看个实际的例子,假设我们想要创建一个HMTL页面生成器,HTML页面的基本结构(构造组件)通常是一 ...

  9. Java设计模式之创建型模式

    创建型模式分为五类:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式 一.工厂方法模式:接口-实现类.工厂类

随机推荐

  1. 生成树计数模板 spoj 104 (不用逆元的模板)

    /* 这种题,没理解,只是记一记如何做而已: 生成树的计数--Matrix-Tree定理 题目:SPOJ104(Highways) 题目大意: *一个有n座城市的组成国家,城市1至n编号,其中一些城市 ...

  2. stl队列

    队列(Queue)也是一种运算受限的线性表,它的运算限制与栈不同,是两头都有限制,插入只能在表的一端进行(只进不出),而删除只能在表的另一端进行(只出不进),允许删除的一端称为队尾(rear),允许插 ...

  3. APP项目下载及运行

    1.首先下载Git 2.再下载安装node.js 3.dos窗口下载node.js依赖jar包 执行命令:npm install 4.从Git上down项目 5.运行项目 在项目根目录下 右键 打开 ...

  4. Abaqus 载荷分类(部分)

    目录 1. 集中载荷 1.1 集中载荷施加方法 1.2 定义集中跟随力 1.3 指定文件定义集中节点力 2. 分布载荷 2.1 分布载荷分类 3. 热载荷 3.1 模拟热辐射 3.2 直接定义热流量 ...

  5. bodyParser.urlencoded({ })里extended: true和false区别???

  6. jvm字节码助记符

    反编译指令 javap -c xxxx.class JVM参数设置 -xx:+<option>                  开启option -xx: -<option> ...

  7. HttpClient的CircularRedirectException解决办法

    解决方法: HttpGet httpGet = new HttpGet(" http://XXXX.XXX"); httpGet.getParams().setParameter( ...

  8. 集合转换为数组toArray(),数组转换为集合asList()

    package seday12; import java.util.ArrayList;import java.util.Arrays;import java.util.Collection; /** ...

  9. MySQL常用系统表大全

    MySQL5.7 默认的模式有:information_schema, 具有 61个表: m ysqL, 具有31个表: performance_schema,具有87个表; sys, 具有1个表, ...

  10. 基于Ubuntu和基于Debian的Linux Mint 20新特性一览

    导读 Linux Mint 20 将基于 Ubuntu 20.04 LTS,同时,其 LMDE(Linux Mint Debian Edition,Debian 版本)4 也将到来,LMDE 版本基于 ...