第六章:建造者模式
一、问题引入
现在要求我们生产电脑,有笔记本电脑、台式电脑。电脑的生产过程工序繁多,不过好在各种电脑的生产过程大致相似。
传统实现方式:
电脑抽象类:
@Data
@ToString
public abstract class Computer {
private String mainboard;
private String memery;
private String cpu;
private String gpu;
private String system;
public abstract void assembleHost();
public abstract void installSystem();
}
具体子类:
public class Laptop extends Computer {
@Override
public void assembleHost() {
System.out.println("为笔记本准备主板");
setMainboard("惠普 836B ( 100 Series/C230 Series 芯片组 Family - A152 )");
System.out.println("为笔记本安装内存");
setMemery("8 GB ( 镁光 DDR4 2666MHz )");
System.out.println("为笔记本安装 cpu");
setCpu("英特尔 Core i5-7300HQ @ 2.50GHz 四核");
System.out.println("为笔记本安装 gpu");
setGpu("Nvidia GeForce GTX 1050 ( 2 GB / 惠普 )");
}
@Override
public void installSystem() {
System.out.println("为笔记本安装操作系统");
setSystem("win10 家庭版");
}
}
public class Desktop extends Computer {
@Override
public void assembleHost() {
System.out.println("为台式机准备主板");
setMainboard("Z390");
System.out.println("为台式机安装内存");
setMemery("16 GB ( 镁光 DDR4 3600MHz )");
System.out.println("为台式机安装 cpu");
setCpu("AMD 3900X");
System.out.println("为台式机安装 gpu");
setGpu("Nvidia GeForce GT 610");
}
@Override
public void installSystem() {
System.out.println("为台式机安装操作系统");
setSystem("Ubuntu 20.04.3 LTS");
}
}
测试类:
public class BuilderTest {
public static void main(String[] args) {
Desktop desktop = new Desktop();
desktop.assembleHost();
desktop.installSystem();
System.out.println(desktop);
Laptop laptop = new Laptop();
laptop.assembleHost();
laptop.installSystem();
System.out.println(laptop);
}
}
这种方式将产品组装的过程放在了产品类的内部,将产品和生产过程耦合在了一起,为了解耦,我们不妨将生产过程给独立出来
二、建造者模式
建造者模式类图:
Computer 类
@Data
@ToString
public class Computer {
private String mainboard;
private String memery;
private String cpu;
private String gpu;
private String system;
}
Builder 抽象类
public abstract class Builder {
protected Computer computer = new Computer();
public Computer getComputer() {
return computer;
}
// builder 类中定义了建造的各个工序
abstract void assembleHost();
abstract void installSystem();
}
Builder 具体子类
public class DesktopBuilder extends Builder {
@Override
public void assembleHost() {
System.out.println("为台式机准备主板");
computer.setMainboard("Z390");
System.out.println("为台式机安装内存");
computer.setMemery("16 GB ( 镁光 DDR4 3600MHz )");
System.out.println("为台式机安装 cpu");
computer.setCpu("AMD 3900X");
System.out.println("为台式机安装 gpu");
computer.setGpu("Nvidia GeForce GT 610");
}
@Override
public void installSystem() {
System.out.println("为台式机安装操作系统");
computer.setSystem("Ubuntu 20.04.3 LTS");
}
}
public class LaptopBuilder extends Builder{
@Override
public void assembleHost() {
System.out.println("为笔记本准备主板");
computer.setMainboard("惠普 836B ( 100 Series/C230 Series 芯片组 Family - A152 )");
System.out.println("为笔记本安装内存");
computer.setMemery("8 GB ( 镁光 DDR4 2666MHz )");
System.out.println("为笔记本安装 cpu");
computer.setCpu("英特尔 Core i5-7300HQ @ 2.50GHz 四核");
System.out.println("为笔记本安装 gpu");
computer.setGpu("Nvidia GeForce GTX 1050 ( 2 GB / 惠普 )");
}
@Override
public void installSystem() {
System.out.println("为笔记本安装操作系统");
computer.setSystem("win10 家庭版");
}
}
Director 类
@Data
public class Director {
private Builder builder;
// 由 director 来组装产品
public Computer constructProduct() {
builder.assembleHost();
builder.installSystem();
return builder.getComputer();
}
}
测试类
public class BuilderTest {
public static void main(String[] args) {
Director director = new Director();
DesktopBuilder desktopBuilder = new DesktopBuilder();
director.setBuilder(desktopBuilder);
Computer desktop = director.constructProduct();
System.out.println(desktop);
LaptopBuilder laptopBuilder = new LaptopBuilder();
director.setBuilder(laptopBuilder);
Computer laptop = director.constructProduct();
System.out.println(laptop);
}
}
三、注意事项
优点:
1)将产品本身和产品的创建过程解耦,使相同的创建过程可以创建不同的产品对象
2)每个建造者相互独立,因此可以方便的替换具体建造者或添加新的建造者,用户使用不同的具体建造者得到不同的产品对象
3)将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰
缺点:
1)产品的生产过程必须有共同点,限制了使用范围
2)如内部变化复杂,会有很多的建造类,难以维护
与工厂模式的不同之处:
1)工厂模式依旧使用的产品内部的创建方法来创建产品
2)所以如果一个产品对象的创建过程很多的话,不妨使用创建者模式