官方定义:把复杂对象构建与其表示分离,使得同样的构建过程可以创建不同的表示。
个人理解,在创建一个对象的时,需要很多的步骤,而这些步骤基本是保持不变的,例如,画人物,躯干,四肢,头,头上的七窍,人的基本组成是固定不变的,我们把步骤抽象出来成一个建造者接口或抽象类,要生成这个对象,交给建造者去建造,建造者造好,直接获取表示出来。
建造者模式结构图如下:
建造者模式由产品,抽象建造者、具体建造者、指挥者4 个要素构成。指挥者有时也可以不要,后面代码中6.2节有讲解。
建造者模式的主要角色如下:
1.产品(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个零部件。
2.抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品(Product)的方法 getProduct()。
3.具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。
4.指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。
1.封装性好,构建和表示分离。
2.扩展性好,各个具体的建造者相互独立,有利于系统的解耦。
3.客户端不必知道产品内部组成的细节,建造者可以对创建过程逐步细化,而不对其它模块产生任何影响,便于控制细节风险。
1.产品的组成部分必须相同,这限制了其使用范围。
2.如果产品的内部变化复杂,如果产品内部发生变化,则建造者也要同步修改,后期维护成本较大。
1.相同的方法,不同的执行顺序,产生不同的结果。
2.多个部件或零件,都可以装配到一个对象中,但是产生的结果又不相同。
3.产品类非常复杂,或者产品类中不同的调用顺序产生不同的作用。
4.初始化一个对象特别复杂,参数多,而且很多参数都具有默认值。
建造者模式唯一区别于工厂模式的是针对复杂对象的创建。也就是说,如果创建简单对象,通常都是使用工厂模式进行创建,而如果创建复杂对象,就可以考虑使用建造者模式。
具体来说,有以下几方面区别:
1.建造者模式更加注重方法的调用顺序,工厂模式注重创建对象。
2.创建对象的力度不同,建造者模式创建复杂的对象,由各种复杂的部件组成,工厂模式创建出来的对象都一样
3.关注重点不一样,工厂模式只需要把对象创建出来就可以了,而建造者模式不仅要创建出对象,还要知道对象由哪些部件组成。
4.建造者模式根据建造过程中的顺序不一样,最终对象部件组成也不一样。
代码示例包含两个部分,一个部分是Director、Builder和Product形成的建造者模式,另一个部分是通过静态内部类方式实现零件无序装配话构造。
电脑(product)组装,有主板,CPU,内存,硬盘,机箱壳,五个步骤,建造者富士康负责为我们组装,联想是我们的指挥者,我们买电脑不找富士康,找联想就可以了。
/**
* @program: design-pattern-learning
* @author: zgr
* @create: 2021-09-26 11:08
**/
public class Computer {
List components = new ArrayList<>();
public void show(){
System.out.println("computer include: ");
for (String s: components) {
System.out.println(s);
}
}
}
/**
* @program: design-pattern-learning
* @author: zgr
* @create: 2021-09-26 11:11
**/
public interface ComputerBuilder {
/**
* 组装主板
*/
void constructBoard();
/**
* 组装cpu
*/
void constructCpu();
/**
* 组装内存条
*/
void constructMemory();
/**
* 组装硬盘
*/
void constructHardDisk();
/**
* 组长机箱壳
*/
void constructCase();
/**
* 返回电脑成品
* @return 电脑
*/
Computer getComputer();
}
/**
* @program: design-pattern-learning
* @author: zgr
* @create: 2021-09-26 11:20
**/
public class FoxconnBuilder implements ComputerBuilder{
private Computer computer = new Computer();
@Override
public void constructBoard() {
computer.components.add("lenovo board");
}
@Override
public void constructCpu() {
computer.components.add("lenovo cpu");
}
@Override
public void constructMemory() {
computer.components.add("lenovo memory");
}
@Override
public void constructHardDisk() {
computer.components.add("lenovo hard disk");
}
@Override
public void constructCase() {
computer.components.add("lenovo case");
}
@Override
public Computer getComputer(){
return computer;
}
}
/**
* @program: design-pattern-learning
* @author: zgr
* @create: 2021-09-26 11:31
**/
public class LenovoDirector {
private ComputerBuilder computerBuilder;
public LenovoDirector(ComputerBuilder computerBuilder){
this.computerBuilder = computerBuilder;
}
public Computer getComputer(){
computerBuilder.constructBoard();
computerBuilder.constructCpu();
computerBuilder.constructMemory();
computerBuilder.constructHardDisk();
computerBuilder.constructCase();
return computerBuilder.getComputer();
}
}
public class MainClass {
public static void main(String[] args) {
LenovoDirector lenovoDirector = new LenovoDirector(new FoxconnBuilder());
Computer computer = lenovoDirector.getComputer();
computer.show();
}
}
手机(product)组装,有主板,CPU,存储,手机壳四个步骤,建造者广达负责为我们组装,apple直接找广达提货拿到手机,不要指挥者,广达组装手机的四个步骤可以根据需要进行调换。
/**
* @program: design-pattern-learning
* @author: zgr
* @create: 2021-09-26 11:08
**/
public class Telephone {
List components = new ArrayList<>();
public void show(){
System.out.println("telephone include: ");
for (String s: components) {
System.out.println(s);
}
}
}
/**
* @program: design-pattern-learning
* @author: zgr
* @create: 2021-09-26 12:06
**/
public interface TelephoneBuilder {
/**
* 组装主板
* @return 手机构建者
*/
TelephoneBuilder constructBoard();
/**
* 组装cpu
* @return 手机构建者
*/
TelephoneBuilder constructCpu();
/**
* 组装存储
* @return 手机构建者
*/
TelephoneBuilder constructMemory();
/**
* 组长手机壳
* @return 手机构建者
*/
TelephoneBuilder constructCase();
/**
* 返回电脑成品
* @return 电脑
*/
Telephone getTelephone();
}
/**
* @program: design-pattern-learning
* @author: zgr
* @create: 2021-09-26 12:04
**/
public class QuantaBuilder implements TelephoneBuilder{
private Telephone telephone;
public QuantaBuilder(){
this.telephone = new Telephone();
}
@Override
public TelephoneBuilder constructBoard() {
telephone.components.add("apple board");
return this;
}
@Override
public TelephoneBuilder constructCpu() {
telephone.components.add("apple cpu");
return this;
}
@Override
public TelephoneBuilder constructMemory() {
telephone.components.add("apple memory");
return this;
}
@Override
public TelephoneBuilder constructCase() {
telephone.components.add("apple case");
return this;
}
@Override
public Telephone getTelephone() {
return telephone;
}
}
/**
* @program: design-pattern-learning
* @author: zgr
* @create: 2021-09-26 11:08
**/
public class MainClass {
public static void main(String[] args) {
QuantaBuilder quantaBuilder = new QuantaBuilder();
Telephone telephone = quantaBuilder.
constructBoard()
.constructMemory()
.constructCpu()
.constructCase()
.getTelephone();
telephone.show();
}
}
两种代码实现,第一种有指挥者适用于建造步骤不变的情况,第二种静态内部类实现方式灵活,对各步骤的先后顺序没有特别要求。
1.《大话设计模式》
2.秒懂设计模式之建造者模式(Builder pattern)
3.建造者模式(Bulider模式)详解
4.Java 设计模式——建造者模式(Builder Pattern)
design-pattern-learning/src/com/hz/design/pattern/builder at main · airhonor/design-pattern-learning · GitHub