前言:
很多设计模式,都继承到了spring中,比如说模板模式,单例模式,代理模式,观察者模式等等,以至于我们平时都没有感觉到自己用到了设计模式,那今天讲到的这个建造者模式,学会了真的是可以用起来,是你的代码更加优雅的。
- 什么是建造者模式
当我们想要创建一个复杂对象的时候,我们通常都是把他的属性,都准备好,然后利用全参数构造把它创建出来,但是,这有一个弊端: 如果我想要一个对象,它没必要那么多属性呢,只需要两个,三个,那聪明的你肯定会想到再来个重载的构造呗!
回答正确,但是,需求总是无限,你准备按照排列组合,把所有的构造方法都写出来吗,那必然是有点拉跨的。这时候,就可以用到建造者模式。
在建造者模式中,主要有以下四个角色:
- 产品(Product):最终要构建的复杂对象,通常包含多个组成部分,如汽车包含引擎、轮胎等。
- 抽象建造者(Builder):定义构建产品的接口,规定了构建产品的各个步骤。
- 具体建造者(Concrete Builder):实现Builder接口,提供构建产品的具体实现,并负责具体产品的构建过程。具体建造者通常会提供一个获取最终构建结果的方法。
- 指挥者(Director):负责安排已有模块的构建步骤,指导具体建造者构建出产品。它不依赖于具体的建造者。
建造者模式的主要优点如下:
- 易于解耦:由于建造者独立于具体产品类,因此容易扩展和修改具体产品类。
- 易于控制细节风险:由于建造者之间独立,因此可以很方便地替换具体建造者或修改具体建造者的实现,而不会对其他模块产生影响。
- 易于扩展:由于指挥者类针对抽象建造者编程,增加新的具体建造者无需修改原有类库的代码,符合"开闭原则"。
在实际应用中,例如,当需要创建一个复杂对象,且这个对象内部有很多属性,且这些属性之间存在一定的构建顺序时,就可以使用建造者模式来简化对象的创建过程。
- 如何使用建造者模式
java
public class Person {
private final String name;
private final int age;
private final String car;
private final String house;
public Person (Builder builder) {
this.name = builder.name;
this.age = builder.age;
this.car = builder.car;
this.house = builder.house;
}
public static class Builder {
private String name;
private int age;
private String car;
private String house;
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setAge(int age) {
this.age = age;
return this;
}
public Builder setCar(String car) {
this.car = car;
return this;
}
public Builder setHouse(String house) {
this.house = house;
return this;
}
public Person build() {
return new Person(this);
}
}
}
3. 我们用建造者模式来创建对象,看看有啥好处
我们来创建一个马云,身价过亿,车,房都是好的
然后再创建一个felix, 不过我就比较特别,我甚至都没车没房,但是我们用了建造者模式,也不需要再写一个重载方法了,代码如下:
java
public static void main(String[] args) {
Person jackMa = new Builder().setName("马云")
.setAge(62)
.setCar("劳斯莱斯")
.setHouse("汤臣一品")
.build();
Person felix = new Builder().setName("Felix")
.setAge(28)
.build();
System.out.println(jackMa);
System.out.println(felix);
}
//输出结果
D:\jdk8\bin\java.exe "-javaagent:D:\software\IntelliJ IDEA 2020.3.3\lib\idea_rt.jar=63808:D:\software\IntelliJ IDEA 2020.3.3\bin" -Dfile.encoding=UTF-8 -classpath D:\jdk8\jre\lib\charsets.jar;D:\jdk8\jre\lib\ext\access-bridge-64.jar;D:\jdk8\jre\lib\ext\cldrdata.jar;D:\jdk8\jre\lib\ext\dnsns.jar;D:\jdk8\jre\lib\ext\jaccess.jar;D:\jdk8\jre\lib\ext\jfxrt.jar;D:\jdk8\jre\lib\ext\localedata.jar;D:\jdk8\jre\lib\ext\nashorn.jar;D:\jdk8\jre\lib\ext\sunec.jar;D:\jdk8\jre\lib\ext\sunjce_provider.jar;D:\jdk8\jre\lib\ext\sunmscapi.jar;D:\jdk8\jre\lib\ext\sunpkcs11.jar;D:\jdk8\jre\lib\ext\zipfs.jar;D:\jdk8\jre\lib\jce.jar;D:\jdk8\jre\lib\jfr.jar;D:\jdk8\jre\lib\jfxswt.jar;D:\jdk8\jre\lib\jsse.jar;D:\jdk8\jre\lib\management-agent.jar;D:\jdk8\jre\lib\resources.jar;D:\jdk8\jre\lib\rt.jar;D:\code\felix\out\production\patterns Person
Person{name='马云', age=62, car='劳斯莱斯', house='汤臣一品'}
Person{name='Felix', age=28, car='null', house='null'}
哈哈哈哈,这个例子是不是很生动形象,就是有点小扎心。
好的,今天就是给大家带来的建造者模式的讲解。