建造者模式(Builder Pattern)也叫做生成器模式,是 GoF 的 23 种设计模式的一种,它将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 当我们需要实列化一个复杂的类,以得到不同结构类型和不同的内部状态的对象时,我们可以用不同的类对它们的实列化操作逻辑分别进行封装,这些类我们就称之为建造者。 ~ 本篇内容包括:关于建造者模式、建造者模式 Demo、使用建造者模式进行重构
建造者模式(Builder Pattern)也叫做生成器模式,是 GoF 的 23 种设计模式的一种,它将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
当我们需要实列化一个复杂的类,以得到不同结构类型和不同的内部状态的对象时,我们可以用不同的类对它们的实列化操作逻辑分别进行封装,这些类我们就称之为建造者。
当我们需要来自同一个类,但是要就有不同结构对象时,就可以通过构造另一个建造者来进行实列化。
建造者(Builder)模式创建的是复杂对象,其产品的各个部分经常面临着剧烈的变化,但将它们组合在一起的算法却相对稳定,所以它通常在以下场合使用。
建造者模式包含如下角色:
# 优点
# 缺点
生产汽车是一个复杂的过程,它包含了车架,车座等等组件的生产,而车架又有碳纤维,铝合金等材质的,车座有橡胶,真皮等材质。对于汽车的生产就可以使用建造者模式。
# Car 产品类
public class Car {
/**
* 车架
*/
private String frame;
/**
* 座椅
*/
private String seat;
public String getFrame() {
return frame;
}
public void setFrame(String frame) {
this.frame = frame;
}
public String getSeat() {
return seat;
}
public void setSeat(String seat) {
this.seat = seat;
}
}
# Builder 抽象建造者类
public abstract class Builder {
protected Car car = new Car();
/**
* 建造车架
*/
public abstract void buildFrame();
/**
* 建造座椅
*/
public abstract void buildSeat();
/**
* 造车
*
* @return Car
*/
public abstract Car createCar();
}
# ACarBulider 具体建造者类
public class ACarBuilder extends Builder {
@Override
public void buildFrame() {
car.setFrame("铝合金车架");
}
@Override
public void buildSeat() {
car.setSeat("真皮车座");
}
@Override
public Car createCar() {
return car;
}
}
# BCarBulider 具体建造者类
public class BCarBuilder extends Builder {
@Override
public void buildFrame() {
car.setFrame("碳纤维车架");
}
@Override
public void buildSeat() {
car.setSeat("皮革车座");
}
@Override
public Car createCar() {
return car;
}
}
# Director 指挥者类
public class Director {
private final Builder mBuilder;
public Director(Builder builder) {
mBuilder = builder;
}
public Car construct() {
mBuilder.buildFrame();
mBuilder.buildSeat();
return mBuilder.createCar();
}
}
public class Client {
private static void showCar(Builder builder) {
Director director = new Director(builder);
Car car = director.construct();
System.out.println(car.getFrame());
System.out.println(car.getSeat());
}
public static void main(String[] args) {
showCar(new ACarBuilder());
showCar(new BCarBuilder());
}
}
建造者模式除了上面的用途外,在开发中还有一个常用的使用方式,就是当一个类构造器需要传入很多参数时,如果创建这个类的实例,代码可读性会非常差,而且很容易引入错误,此时就可以利用建造者模式进行重构。
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 + '\'' +
'}';
}
}
public class Client {
public static void main(String[] args) {
//构建Phone对象
Phone phone = new Phone("intel", "三星屏幕", "金士顿", "华硕");
System.out.println(phone);
}
}
public class Phone {
private String cpu;
private String screen;
private String memory;
private String mainboard;
private Phone(Builder builder) {
cpu = builder.cpu;
screen = builder.screen;
memory = builder.memory;
mainboard = builder.mainboard;
}
public static final class Builder {
private String cpu;
private String screen;
private String memory;
private String mainboard;
public Builder() {
}
public Builder cpu(String val) {
cpu = val;
return this;
}
public Builder screen(String val) {
screen = val;
return this;
}
public Builder memory(String val) {
memory = val;
return this;
}
public Builder mainboard(String val) {
mainboard = val;
return this;
}
public Phone build() {
return new Phone(this);
}
}
@Override
public String toString() {
return "Phone{" +
"cpu='" + cpu + '\'' +
", screen='" + screen + '\'' +
", memory='" + memory + '\'' +
", mainboard='" + mainboard + '\'' +
'}';
}
}
public class Client {
public static void main(String[] args) {
Phone phone = new Phone.Builder()
.cpu("intel")
.mainboard("华硕")
.memory("金士顿")
.screen("三星")
.build();
System.out.println(phone);
}
}