目录
六、建造者模式
1、概述
2、应用场景
3、优缺点
优点
缺点
4、主要角色
5、代码实现
产品类
抽象建造者
具体建造者
指挥者
测试类
测试结果
6、建造者模式和工厂模式的区别
六、建造者模式
1、概述
第二次梳理:建造者模式中,产品是固定的,规定了产品的结构;抽象建造者是固定的,规定了建造的环节有哪些;具体建造者是不同的,不同的具体建造者建造出的结果是不同的;另外指挥者所指定的不同逻辑也会影响建造的最终结果!时间:2021年05月14日 10时04分47秒
工厂模式创建了各种各样的对象,这些对象可以是一个复杂产品的配件,比如计算机的配件有CPU、显卡、硬盘等,建造者模式就是将这些配件组装成一个完整的产品,也就是说建造者模式是将简单的对象组合成复杂的对象!
在软件开发过程中有时需要创建一个复杂的对象,这个复杂对象通常由多个子部件按一定的步骤组合而成。例如,计算机是由 CPU、主板、内存、硬盘、显卡、机箱、显示器、键盘、鼠标等部件组装而成的,采购员不可能自己去组装计算机,而是将计算机的配置要求告诉计算机销售公司,计算机销售公司安排技术人员去组装计算机,然后再交给要买计算机的采购员。
生活中这样的例子很多,如游戏中的不同角色,其性别、个性、能力、脸型、体型、服装、发型等特性都有所差异;还有汽车中的方向盘、发动机、车架、轮胎等部件也多种多样;每封电子邮件的发件人、收件人、主题、内容、附件等内容也各不相同。
建造者模式:指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。
意思就是:我要组装一台台式机电脑,所需要的配置就是那几样,CPU、显卡、内存、硬盘什么的,这些是不变的,但是我可以选择很多品牌的配件,我可以选择英特尔的CPU、AMD的显卡等等。
2、应用场景
建造者模式唯一区别于工厂模式的是针对复杂对象的创建。也就是说,如果创建简单对象,通常都是使用工厂模式进行创建,而如果创建复杂对象,就可以考虑使用建造者模式。
当需要创建的产品具备复杂创建过程时,可以抽取出共性创建过程,然后交由具体实现类自定义创建流程,使得同样的创建行为可以生产出不同的产品,分离了创建与表示,使创建产品的灵活性大大增加。
- 相同的方法,不同的执行顺序,产生不同的结果;
- 多个部件或零件,都可以装配到一个对象中,但是产生的结果又不相同;
- 产品类非常复杂,或者产品类中不同的调用顺序产生不同的作用;
- 初始化一个对象特别复杂,参数多,而且很多参数都具有默认值;
3、优缺点
优点
- 封装性好,构建和表示分离;
- 扩展性好,各个具体的建造者相互独立,有利于系统的解耦;
- 客户端不必知道产品内部组成的细节,建造者可以对创建过程逐步细化,而不对其它模块产生任何影响,便于控制细节风险;
缺点
- 产品的组成部分必须相同,这限制了其使用范围;
- 如果产品的内部变化复杂,如果产品内部发生变化,则建造者也要同步修改,后期维护成本较大;
4、主要角色
产品角色就是建造的目标,包含各种配件;抽象建造者规定了都需要建造哪些部件(或者是建造的环节),具体建造任务交给具体建造者,具体建造者可以是不同的主体,就像是一台电脑的配件就是那么几件,但是不同的配件厂商制造出的配件特性不一样,符合不同消费者的需求;指挥者就是设置一个建造的逻辑,将各个建造步骤联系起来,完成产品建造流程!这里具体建造者和指挥者都可以是不同的主体,也就是不同的”方案“!一切可以灵活调整!
建造者(Builder)模式在应用过程中可以根据需要改变,如果创建的产品种类只有一种,只需要一个具体建造者,这时可以省略掉抽象建造者,甚至可以省略掉指挥者角色。
- 产品角色(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个零部件;
- 抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 getResult();
- 具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法;
- 指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息;
5、代码实现
产品类
package com.zibo.design.two;
// 产品角色
public class Computer {
private String mainBoard;
private String cpu;
private String displayCard;
private String hardDisk;
private String other;
public void setCpu(String cpu) {
this.cpu = cpu;
}
public void setDisplayCard(String displayCard) {
this.displayCard = displayCard;
}
public void setHardDisk(String hardDisk) {
this.hardDisk = hardDisk;
}
public void setOther(String other) {
this.other = other;
}
public void setMainBoard(String mainBoard) {
this.mainBoard = mainBoard;
}
@Override
public String toString() {
return "Computer{" +
"mainBoard='" + mainBoard + ''' +
", cpu='" + cpu + ''' +
", displayCard='" + displayCard + ''' +
", hardDisk='" + hardDisk + ''' +
", other='" + other + ''' +
'}';
}
}
抽象建造者
package com.zibo.design.two;
// 装机的各个环节
public abstract class Builder {
// 装主板
public abstract void buildMainBoard();
// 装CPU
public abstract void buildCPU();
// 装显卡
public abstract void buildDisplayCard();
// 装硬盘
public abstract void buildHardDisk();
// 装其它配件
public abstract void buildOther();
// 获得组装好的电脑
public abstract Computer getComputer();
}
具体建造者
package com.zibo.design.two;
// 具体的装机操作
public class ConcreteBuilder extends Builder {
// 创建空对象,然后往空对象里面组装配件
Computer computer = new Computer();
@Override
public void buildCPU() {
computer.setCpu("R7-5800H");
}
@Override
public void buildDisplayCard() {
computer.setDisplayCard("RTX 2060");
}
@Override
public void buildMainBoard() {
computer.setMainBoard("某X99主板");
}
@Override
public void buildHardDisk() {
computer.setHardDisk("某SSD固态硬盘");
}
@Override
public void buildOther() {
computer.setOther("其他配件");
}
@Override
public Computer getComputer() {
return computer;
}
}
指挥者
package com.zibo.design.two;
// 装机员装机,整合各个步骤
public class Director {
public void construct(Builder builder) {
builder.buildMainBoard();
builder.buildCPU();
builder.buildDisplayCard();
builder.buildHardDisk();
builder.buildOther();
}
}
测试类
package com.zibo.design.two;
public class BuilderPattern {
public static void main(String[] args) {
// 装机员对象
Director director = new Director();
// 构造器
Builder builder = new ConcreteBuilder();
// 装机
director.construct(builder);
// 获取装好的电脑
Computer computer = builder.getComputer();
// 打印相关信息
System.out.println(computer);
}
}
测试结果
Computer{mainBoard='某X99主板', cpu='R7-5800H', displayCard='RTX 2060', hardDisk='某SSD固态硬盘', other='其他配件'}
6、建造者模式和工厂模式的区别
- 建造者模式更加注重方法的调用顺序,工厂模式注重创建对象;
- 创建对象的力度不同,建造者模式创建复杂的对象,由各种复杂的部件组成,工厂模式创建出来的对象都一样;
- 关注重点不一样,工厂模式只需要把对象创建出来就可以了,而建造者模式不仅要创建出对象,还要知道对象由哪些部件组成;
- 建造者模式根据建造过程中的顺序不一样,最终对象部件组成也不一样;