学习设计模式 - 建造者模式
一、是什么
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。(Spearate the construction of a compolex object from its representation so that the same construction process can create different representations.)
二、为什么
1. 如果一个对象的组成过于复杂,可以通过建造者模式,将构造过程抽离出来,一步步构造对象
2. 可以更精细的控制生成对象
3. 由于对象构造过程过于复杂, 使用建造者模式可以屏蔽对象的内部复杂性, 减少客户端对复杂对象的了解
三、怎么样

3.1) Product产品类:
需要构建复杂的产品类
3.2) Builder构建接口
可定义了构建部分构建的接口方法, 以及构建整个对象的方法.
3.3) ConreteBuilder具体构建者
实现了Builder接口.
3.3) Direct导演类
导演类一方面封装导演了构建组件的构成, 另一方面屏蔽客户端对构建过程的深入了解.
四、举例
1. 产品类
public class Computer {
private String cpu;
private String memory;
private String hardDisk;
public String getCpu() {
return cpu;
}
public void setCpu(String cpu) {
this.cpu = cpu;
}
public String getMemory() {
return memory;
}
public void setMemory(String memory) {
this.memory = memory;
}
public String getHardDisk() {
return hardDisk;
}
public void setHardDisk(String hardDisk) {
this.hardDisk = hardDisk;
}
@Override public String toString() {
return "computer= { cpu: "+cpu+", memory: "+memory+", hardDisk: "+hardDisk+"} ";
}
}
2. 定义建造者接口
public interface ComputerBuilder {
ComputerBuilder setCpu();
ComputerBuilder setMemory();
ComputerBuilder setHardDisk();
Computer build();
}
3. 实现多种具体建造者
public class HighConfComputerBuilder implements ComputerBuilder { // 高配电脑建造者
private Computer computer;
public HighConfComputerBuilder() {
this.computer=new Computer();
}
@Override public ComputerBuilder setCpu() {
this.computer.setCpu("i7处理器");
return this;
}
@Override public ComputerBuilder setMemory() {
this.computer.setMemory("16G内存");
return this;
}
@Override public ComputerBuilder setHardDisk() {
this.computer.setHardDisk("1T固态硬盘");
return this;
}
@Override public Computer build() {
return this.computer;
}
}
public class LowConfComputerBuilder implements ComputerBuilder { // 低配电脑建造者
private Computer computer;
public LowConfComputerBuilder() {
this.computer=new Computer();
}
@Override public ComputerBuilder setCpu() {
this.computer.setCpu("i3处理器");
return this;
}
@Override public ComputerBuilder setMemory() {
this.computer.setMemory("4G内存条");
return this;
}
@Override public ComputerBuilder setHardDisk() {
this.computer.setHardDisk("500G机械硬盘");
return this;
}
@Override public Computer build() {
return this.computer;
}
}
4. 导演类
/**
* 导演类, 避免客户端代码深入建造过程
* @author TimFruit
* @date 2019/7/2 14:28
*/
public class ComputerDirector {
public Computer buildHighConfigComputer(){
ComputerBuilder cb=new HighConfComputerBuilder();
// 封装构建过程, 按照"蓝图"导演构造产品
cb.setCpu()
.setMemory()
.setHardDisk();
return cb.build();
}
public Computer buildLowConfigComputer(){
ComputerBuilder cb=new LowConfComputerBuilder();
// 封装构建过程, 按照"蓝图"导演构造产品
cb.setHardDisk()
.setCpu()
.setMemory();
return cb.build();
}
}
5. 测试类
public class Client {
public static void main(String[] args) {
ComputerDirector cd=new ComputerDirector();
Computer lowConfigComputer=cd.buildLowConfigComputer();
System.out.println(lowConfigComputer);
Computer highConfigComputer=cd.buildHighConfigComputer();
System.out.println(highConfigComputer);
}
}
6. 结果
computer= { cpu: i3处理器, memory: 4G内存条, hardDisk: 500G机械硬盘}
computer= { cpu: i7处理器, memory: 16G内存, hardDisk: 1T固态硬盘}
五、注意事项
适用场景:
a. 构造复杂对象,如config,vo等
b. 构造部件的顺序不同, 产生的结果不同, 则可以使用该模式
vs工厂模式:
工厂模式关注的是使用什么工厂, 获得什么产品, 而建造者模式关注的是, 以什么样的顺序构建组装一个产品, 它的侧重点在于构建的过程.
六、变种建造者模式
1. 产品类
public class Person {
private final String name; // 由于定义了不可变类型final
private final int age;
private final int height;
private final String address;
public Person(Builder builder) {
this.name=builder.name;
this.age=builder.age;
this.height=builder.height;
this.address=builder.address;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public int getHeight() {
return height;
}
public String getAddress() {
return address;
}
public static class Builder{ // 建造者为内部类, 一般用于设置产品类的多种属性, 如果仅仅使用构造参数注入, 会使得程序易出错
private final String name;
private int age;
private int height;
private String address;
public Builder(String name) {
this.name = name;
}
public Builder setAge(int age) {
this.age = age;
return this;
}
public Builder setHeight(int height) {
this.height = height;
return this;
}
public Builder setAddress(String address) {
this.address = address;
return this;
}
public Person build(){
return new Person(this);
}
}
}
2. 测试类上下文
public class Client {
public static void main(String[] args){
Person person=new Person.Builder("tim").setAge(11).setHeight(168).setAddress("中国好声音").build();
System.out.println("person: ");
System.out.println("name: "+person.getName());
System.out.println("age: "+person.getAge());
System.out.println("height: "+person.getHeight());
System.out.println("address: "+person.getAddress());
}
}
学习资料:
<设计模式之禅>