- 建造者模式(Builder Pattern)
定义:将一个复杂对象的创建过程与它的表示分离开来,使得同样的创建过程可以创建不同的表示,即尽量做到代码的复用,与工厂方法有点类似,但是建造者适用的是对象的创建相对复杂的场景,可以抽取出抽象的创建过程,然后交给具体的实现类自定义创建流程,使得同样的行为(方法)可以创建出不同的产品
应用场景:比如买一台车,同一个型号有不同的配置,不同配置的车都是出厂与同一个品牌
角色:产品,抽象建造者,建造者,调用者
实际场景应用:
比方说一个产品为汽车,一辆完整的汽车有车轮,方向盘,发动机,中控台等可选配置
那么就创建一个产品类包含这些属性,定义一个抽象创建者接口包含创建的抽象方法,然后实现具体的创建者对象,按需要重写创建方法
在框架中经常使用到链式的创建者写法
public interface Builder {
Car creadCar();
}
public class Car {
private String tyre;
private String steeringWheel;
private String engine;
private String control;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Car car = (Car) o;
return Objects.equals(tyre, car.tyre) &&
Objects.equals(steeringWheel, car.steeringWheel) &&
Objects.equals(engine, car.engine) &&
Objects.equals(control, car.control);
}
@Override
public int hashCode() {
return Objects.hash(tyre, steeringWheel, engine, control);
}
public String getTyre() {
return tyre;
}
public void setTyre(String tyre) {
this.tyre = tyre;
}
public String getSteeringWheel() {
return steeringWheel;
}
public void setSteeringWheel(String steeringWheel) {
this.steeringWheel = steeringWheel;
}
public String getEngine() {
return engine;
}
public void setEngine(String engine) {
this.engine = engine;
}
public String getControl() {
return control;
}
public void setControl(String control) {
this.control = control;
}
@Override
public String toString() {
return "Car{" +
"tyre='" + tyre + '\'' +
", steeringWheel='" + steeringWheel + '\'' +
", engine='" + engine + '\'' +
", control='" + control + '\'' +
'}';
}
}
package com.BuilderPattern;
/**
* @author yangxiaozhen
* @date 2022/5/7-22:14
* 建造者模式的链式编程
*/
public class CarBuilder implements Builder {
private Car car = new Car();
public CarBuilder setTyre(String a){
car.setTyre(a);
return this;
}
public CarBuilder setSteeringWheel(String a){
car.setSteeringWheel(a);
return this;
}
public CarBuilder setControl(String a){
car.setControl(a);
return this;
}
public CarBuilder setEngine(String a){
car.setEngine(a);
return this;
}
@Override
public Car creadCar() {
return car;
}
}
public class TestMain {
public static void main(String[] args) {
CarBuilder carBuilder = new CarBuilder();
carBuilder.setControl("顶配")
.setEngine("顶配")
.setSteeringWheel("顶配")
.setTyre("中配");
Car car = carBuilder.creadCar();
System.out.println(car.toString());
由于创建者模式与建造者模式的功能太相似,有时候经常忽略对象创建的复杂性直接去使用工厂方法因为工厂方法结构更加简洁
一般情况下选择用建造者模式会使用静态内部内的方式来实现,即产品类中自带一个具体的创建者,这样产品的表示和创建过程之间会更加紧密,是优点也是缺点
public class StaticInnerClassBuilder {
private String tyre;
private String steeringWheel;
private String engine;
private String control;
public static class InnerClasscarBuilder {
private StaticInnerClassBuilder staticInnerClassBuilder = new StaticInnerClassBuilder();
public StaticInnerClassBuilder createMid() {
staticInnerClassBuilder.setControl("中档");
staticInnerClassBuilder.setEngine("中档");
staticInnerClassBuilder.setTyre("中档");
staticInnerClassBuilder.setSteeringWheel("中档");
return staticInnerClassBuilder;
}
public StaticInnerClassBuilder createHigh() {
staticInnerClassBuilder.setControl("高档");
staticInnerClassBuilder.setEngine("高档");
staticInnerClassBuilder.setTyre("高档");
staticInnerClassBuilder.setSteeringWheel("高档");
return staticInnerClassBuilder;
}
}
@Override
public String toString() {
return "StaticInnerClassBuilder{" +
"tyre='" + tyre + '\'' +
", steeringWheel='" + steeringWheel + '\'' +
", engine='" + engine + '\'' +
", control='" + control + '\'' +
'}';
}
public String getTyre() {
return tyre;
}
public void setTyre(String tyre) {
this.tyre = tyre;
}
public String getSteeringWheel() {
return steeringWheel;
}
public void setSteeringWheel(String steeringWheel) {
this.steeringWheel = steeringWheel;
}
public String getEngine() {
return engine;
}
public void setEngine(String engine) {
this.engine = engine;
}
public String getControl() {
return control;
}
public void setControl(String control) {
this.control = control;
}
}
工厂方法模式与建造者模式的关系
我认为工厂方法模式和建造者模式最终结果都是封装对象的创建过程,只不过建造者模式更加抽象,如果业务中,某个对象在不同的“构建过程”下,能产生不同的行为,那么我们应该在“工厂方法”的基础上(工厂方法把对象的行为的实现和创建方式的实现隔开来,更像是封装了“new”)把这些具有差异性“构建过程”逐一封装,或者是定义一份用作自定义“构建过程”给用户去自定义。有便于程序将来的扩展
实际应用案例
在编写SQL语句时,经常需要根据不同的条件来拼接SQL字符串,如果查询条件复杂,那么在做字符串拼接的时候也会很复杂,对于代码的维护也不美丽,因此,写一个QueryRuleBuilder将复杂的构建过程进行封装.
...(暂不深入)
JDK中的StringBuilder类,提供了append()方法把“构建过程”提供给用户调用,以便创建具有用户需要的特殊意义的“产品”,而且是返回this,是链式编程建造者模式的方式。