一、什么是建造者模式?
建造者(Builder)设计模式是一种创建型设计模式,其主要目的是为了将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式可以将部件和其组装过程分开,一步一步创建一个复杂的对象。用户只需要指定复杂对象的类型就可以得到该对象,而无须知道其内部的具体构造细节。
二、角色组成
产品类(Product):表示被创建的复杂对象。它通常包含多个部分或者组成,并由具体的建造者逐步构建而成。
抽象建造者类(Builder):定义了建造复杂对象所需要的各个部分的创建方法。它通常包括多个构建方法和一个返回产品的方法。
具体建造者类(ConcreteBuilder):实现Builder接口,并提供各个部分或者组成的构建方法。
指挥者类(Director):负责控制建造者的构建顺序,指挥建造者如何构建复杂对象。
三、应用场景
盒饭套餐:餐厅有多种菜品,顾客可以选择不同的菜,服务员按照顾客的要求,将这些菜组合起来,最终构建出一个完整的套餐。
盖房子:需要分多个阶段进行,比如准备材料、打地基、盖围墙…。建造者模式可以将房屋的建造分解成多个步骤,每个步骤对应一个具体的建造者,最终由包工头(指导者)来调用不同的建造者,完成整个房子的建造。
总的来说是:当创建一个复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。 当构造过程必须允许被构造的对象有不同的表示时。
四、实现
4.1 产品类
public class Phone {
private String cpu;
private String screen;
private String memory;
private String mainboard;
public Phone(String cpu, String screen, String memory, String mainboard) {
this.cpu = cpu;
this.screen = screen;
this.memory = memory;
this.mainboard = mainboard;
}
public String getCpu() {
return cpu;
}
public void setCpu(String cpu) {
this.cpu = cpu;
}
public String getScreen() {
return screen;
}
public void setScreen(String screen) {
this.screen = screen;
}
public String getMemory() {
return memory;
}
public void setMemory(String memory) {
this.memory = memory;
}
public String getMainboard() {
return mainboard;
}
public void setMainboard(String mainboard) {
this.mainboard = mainboard;
}
@Override
public String toString() {
return "Phone{" +
"cpu='" + cpu + '\'' +
", screen='" + screen + '\'' +
", memory='" + memory + '\'' +
", mainboard='" + mainboard + '\'' +
'}';
}
}
4.2 抽象建造者
public interface Builder {
void buildBoard(String board);
void buildCpu(String cpu);
void buildRam(String ram);
void buildHardDisk(String hardDisk);
Phone createPhone();
}
4.3 具体建造者
public class AsusBuilder implements Builder {
private Phone mPhone = new AsusPhone();
@Override
public void buildBoard(String board) {
mPhone.setBoard(board);
}
@Override
public void buildCpu(String cpu) {
mPhone.setCpu(cpu);
}
@Override
public void buildRam(String ram) {
mPhone.setRam(ram);
}
@Override
public void buildHardDisk(String hardDisk) {
mPhone.setHardDisk(hardDisk);
}
@Override
public Phone createPhone() {
return mPhone;
}
}
public class DellBuilder implements Builder {
private Phone mPhone = new DellPhone();
@Override
public void buildBoard() {
mPhone.setBoard("Asus Board");
}
@Override
public void buildCpu() {
mPhone.setCpu("Intel i7-8700K");
}
@Override
public void buildRam() {
mPhone.setRam("16GB DDR4");
}
@Override
public void buildHardDisk() {
mPhone.setHardDisk("1TB SSD");
}
@Override
public Phone createPhone() {
return mPhone;
}
}
public class HPBuilder implements Builder {
private Phone mPhone = new HPPhone();
@Override
public void buildBoard() {
mPhone.setBoard("djkfj");
}
@Override
public void buildCpu() {
mPhone.setCpu("晓龙888");
}
@Override
public void buildRam() {
mPhone.setRam("kdk22 ");
}
@Override
public void buildHardDisk() {
mPhone.setHardDisk("威海");
}
@Override
public Phone createPhone() {
return mPhone;
}
}
4.4 指挥者
public class Director {
private Builder mBuilder;
public Director(Builder builder) {
this.mBuilder = builder;
}
public Phone buildPhone(String board, String cpu, String ram, String hardDisk) {
mBuilder.buildBoard(board);
mBuilder.buildCpu(cpu);
mBuilder.buildRam(ram);
mBuilder.buildHardDisk(hardDisk);
return mBuilder.createPhone();
}
}
4.5 测试类
public class Client {
public static void main(String[] args) {
Builder asusBuilder = new AsusBuilder();
Builder dellBuilder = new DellBuilder();
// 指挥者创建对应的手机
Director director = new Director(asusBuilder);
Phone asusPhone = director.buildPhone();
director = new Director(dellBuilder);
Phone asusPhone = director.buildPhone();
}
}
分析
可以看到,根据不同的需求,建造者模式可以构造出不同的手机对象。每个手机对象的构建过程都由不同的建造者实现,在构建过程中可定制相应的属性。最终,因为手机的构建过程和表示分离,所以同样的构建过程可以创建出不同的表示。
优缺点
建造者模式的优点:
-
将构建复杂对象的过程封装起来,简化了代码结构和逻辑。
-
不同的具体构造者可以实现不同的构建流程,使得同样的构建过程可以创建不同的表示。
-
指导者类可以根据需要按照特定的顺序执行构建流程,从而达到更好的控制和管理对象的构建。
建造者模式的缺点:
- 添加新的部件需要修改抽象类和具体构造者的代码。
- 如果对象的属性较少,使用建造者模式可能会显得过于复杂,不如直接使用工厂方法模式或简单工厂模式。
总之,建造者模式适用于需要创建对象复杂且变化多端的情景,它能够将对象的构建过程标准化,从而达到代码重用和简化的目的。