建造者模式
什么是建造者模式
建造者模式(Builder Pattern)是一种对象构建的设计模式,它允许你通过一步一步地构建一个复杂对象,来隐藏复杂对象的创建细节。
这种模式将一个复杂对象的构建过程与其表示过程分离,使得同样的构建过程可以创建不同的表示。命名建议以Builder结尾,以达到见名之意。
在建造者模式中,通常包含以下几个角色:
- 产品(Product):这是最终要创建的对象,它通常包含多个属性,并且可能具有复杂的内部结构。
- 抽象建造者(Builder):这是一个接口或者抽象类,定义了创建产品所需的方法。这些方法通常是一系列设置产品属性的步骤。
- 具体建造者(ConcreteBuilder):这个类实现了抽象建造者接口,提供了构建产品的具体实现。它包含了创建产品对象的所有逻辑,并可以一步步地设置产品对象的属性。
- 导演者(Director):这是一个可选的角色,它负责调用建造者接口中的方法来构建产品对象。导演者可以简化客户端代码,使得客户端无需关心具体的构建步骤。
使用场景
- 当我们要建造一个复杂的产品。比如:手机时。这种复杂产品的创建,需要处理子组件装配的问题。
- 实际开发中,我们所需要的对象构建时也非常复杂,有很多步骤需要处理时。
建造者模式的本质
- 分离了对象子组件的单独构造(有Buider来负责)和装配(有Director负责)。从而可以构造负责的对象。
- 这个模式适用于在某个对象构建过程复杂的情况下使用。
- 由于实现了构建和装配的解耦。不同的构建器,相同的装配,可以做出不同的对象; 相同的构建器,不同的装配顺序也可以做出不同的对象。也就是实现了构建算法、装配算法的解耦,实现了更好的复用。
案例
实现建造华为手机与小米手机
通过静态内部类作为建造者
Phone.java
public class Phone {
// 机身
private String fuselage;
// 摄像头
private String camera;
// 系统内核
private String systemKernel;
// 私有构造方法,只能通过建造者创建
private Phone(Builder builder) {
this.fuselage = builder.fuselage;
this.camera = builder.camera;
this.systemKernel = builder.systemKernel;
}
@Override
public String toString() {
return "Phone{" +
"fuselage='" + fuselage + '\'' +
", camera='" + camera + '\'' +
", systemKernel='" + systemKernel + '\'' +
'}';
}
// 静态内部类作为建造者
static class Builder {
// 机身
private String fuselage;
// 摄像头
private String camera;
// 系统内核
private String systemKernel;
public Builder setFuselage(String fuselage) {
this.fuselage = fuselage;
return this; // 链式调用
}
public Builder setCamera(String camera) {
this.camera = camera;
return this; // 链式调用
}
public Builder setSystemKernel(String systemKernel) {
this.systemKernel = systemKernel;
return this; // 链式调用
}
// 创建手机
public Phone createPhone(){
return new Phone(this);
}
}
}
Client.java
public class Client {
public static void main(String[] args) {
Phone phone = new Phone.Builder()
.setCamera("华为摄像头")
.setFuselage("华为机身")
.setSystemKernel("鸿蒙系统")
.createPhone();
System.out.println(phone);
Phone phone2 = new Phone.Builder()
.setCamera("小米摄像头")
.setFuselage("小米机身")
.setSystemKernel("小米系统")
.createPhone();
System.out.println(phone2);
}
}
执行结果:
通过接口实现建造者模式
UML
不使用导演者
Phone.java
public class Phone {
// 机身
private String fuselage;
// 摄像头
private String camera;
// 系统内核
private String systemKernel;
public void setFuselage(String fuselage) {
this.fuselage = fuselage;
}
public void setCamera(String camera) {
this.camera = camera;
}
public void setSystemKernel(String systemKernel) {
this.systemKernel = systemKernel;
}
@Override
public String toString() {
return "Phone{" +
"fuselage=" + fuselage +
", camera=" + camera +
", systemKernel=" + systemKernel +
'}';
}
}
IPhoneBuider.java
// 手机 抽象建造者定义接口
public interface IPhoneBuider {
// 设置机身
IPhoneBuider setFuselage(String fuselage);
// 设置摄像头
IPhoneBuider setCamera(String camera);
// 设置系统内核
IPhoneBuider setSystemKernel(String systemKernel);
// 返回创建对象
Phone buildPhone();
}
PhoneBuilder.java
// 建造者具体实现
public class PhoneBuilder implements IPhoneBuider {
// 定义建造者返回对象
private Phone phone;
public PhoneBuilder() {
// 初始化Phone
this.phone = new Phone();
}
@Override
public IPhoneBuider setFuselage(String fuselage) {
phone.setFuselage(fuselage);
return this;
}
@Override
public IPhoneBuider setCamera(String camera) {
phone.setCamera(camera);
return this;
}
@Override
public IPhoneBuider setSystemKernel(String systemKernel) {
phone.setSystemKernel(systemKernel);
return this;
}
@Override
public Phone buildPhone() {
return phone;
}
}
TestClient2.java
public class TestClient2 {
public static void main(String[] args) {
// 创建建造具体建造者
PhoneBuilder phoneBuilder = new PhoneBuilder();
Phone phone = phoneBuilder
.setCamera("装配小米摄像头")
.setFuselage("装配小米机身")
.setSystemKernel("装配小米系统")
.buildPhone();
System.out.println(phone.toString());
}
}
使用导演者
新增导演者
HuaweiDirector.java
// 华为手机导演者
public class HuaweiDirector {
// 定义建造者属性
private IPhoneBuider phoneBuider;
public HuaweiDirector(IPhoneBuider phoneBuider) {
this.phoneBuider = phoneBuider;
}
public Phone createPhone(){
Phone phone = phoneBuider.setCamera("装配华为摄像头")
.setFuselage("装配华为机身")
.setSystemKernel("装配鸿蒙系统")
.buildPhone();
return phone;
}
}
TestClient.java
public class TestClient {
public static void main(String[] args) {
// 创建建造具体建造者
PhoneBuilder phoneBuilder = new PhoneBuilder();
// 创建导演者 传入具体建造者
HuaweiDirector huaweiDirector = new HuaweiDirector(phoneBuilder);
// 通过导演者构建手机
Phone phone = huaweiDirector.createPhone();
System.out.println(phone.toString());
}
}