建造者模式
建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。
意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
何时使用:==一些基本部件不会变,而其组合经常变化的时候。==
如何解决:将变与不变分离开。
优点:
- 建造者独立,易扩展。
- 便于控制细节风险。
缺点:
1. 产品必须有共同点,范围有限制。
2. 如内部变化复杂,会有很多的建造类。
使用场景: 1、需要生成的对象具有复杂的内部结构。 2、需要生成的对象内部属性本身相互依赖。
注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。而工厂更专注于零件的制造过程。
现在需要构建很多车辆,车的组成有车轮、外壳、发动机、方向盘等,每个组件有不同品牌,最后需要根据客户需求定制不同的车。(车的总体组成是一样的,组成部件变化)
/**
* @author objcfeng
* @description 车的实体类
* @date 2020/11/2
*/
public class Car {
//车轮
private String wheel;
//外壳
private String shell;
//发动机
private String engine;
//方向盘
private String steeringWheel;
@Override
public String toString() {
return "Car{" +
"wheel='" + wheel + '\'' +
", Shell='" + shell + '\'' +
", engine='" + engine + '\'' +
", steeringWheel='" + steeringWheel + '\'' +
'}';
}
public String getWheel() {
return wheel;
}
public void setWheel(String wheel) {
this.wheel = wheel;
}
public String getShell() {
return shell;
}
public void setShell(String shell) {
this.shell = shell;
}
public String getEngine() {
return engine;
}
public void setEngine(String engine) {
this.engine = engine;
}
public String getSteeringWheel() {
return steeringWheel;
}
public void setSteeringWheel(String steeringWheel) {
this.steeringWheel = steeringWheel;
}
}
//车的建造者
public abstract class CarBuilder {
//造车轮的方法,因为实际上车轮可能是一个复杂对象
public abstract void buildWheel();
//造外壳的方法
public abstract void buildShell();
//造引擎的方法
public abstract void buildEngine();
//造方向盘的方法
public abstract void buildSteeringWheel();
public abstract Car getCar();
}
建造者实现类,多个品牌组装不同的组件
/**
* @author objcfeng
* @description 奔驰建造者
* @date 2020/11/2
*/
public class BenzBuilder extends CarBuilder {
private Car car=new Car();
@Override
public void buildWheel() {
car.setWheel("上好的车轮");
}
@Override
public void buildShell() {
car.setShell("奔驰外壳");
}
@Override
public void buildEngine() {
car.setEngine("奔驰产发动机");
}
@Override
public void buildSteeringWheel() {
car.setSteeringWheel("有奔驰标识的方向盘");
}
@Override
public Car getCar() {
return car;
}
}
/**
* @author objcfeng
* @description 宝马建造者
* @date 2020/11/2
*/
public class BmwBuilder extends CarBuilder {
private Car car=new Car();
@Override
public void buildWheel() {
car.setWheel("上好的车轮");
}
@Override
public void buildShell() {
car.setShell("宝马外壳");
}
@Override
public void buildEngine() {
car.setEngine("宝马产发动机");
}
@Override
public void buildSteeringWheel() {
car.setSteeringWheel("有宝马标识的方向盘");
}
@Override
public Car getCar() {
return car;
}
}
指挥者
/**
* @author objcfeng
* @description 指挥者,指导具体构建者如何构建产品,控制调用先后次序,并向调用者返回完整的产品类
* @date 2020/11/2
*/
public class CarDirector {
private CarBuilder builder;
public CarDirector(CarBuilder builder) {
this.builder = builder;
}
public Car build(){
builder.buildEngine();
builder.buildShell();
builder.buildSteeringWheel();
builder.buildWheel();
return builder.getCar();
}
}
使用:
public class Main {
public static void main(String[] args) {
CarBuilder builder1=new BmwBuilder();
CarBuilder builder2=new BenzBuilder();
CarDirector carDirector = new CarDirector(builder1);
Car car = carDirector.build();
System.out.println(car);
}
}
输出
Car{wheel='上好的车轮', Shell='宝马外壳', engine='宝马产发动机', steeringWheel='有宝马标识的方向盘'}
我们发现,在CarBuilder的实现类中,总是有个重写的getCar方法返回创建好的Car对象,并且CarBuilder的子类总是需要构建一个新的car对象。因为一个car对象只会被一个CarBuilder创建,因此,可以将car对象提升到CarBuilder抽象类中创建。如下,
//建造者
public abstract class CarBuilder {
//新增创建一个新的car对象
protected Car car = new Car();
//其他方法不变
public abstract void buildWheel();
public abstract void buildShell();
public abstract void buildEngine();
public abstract void buildSteeringWheel();
//修改返回car对象方法
public Car getCar(){
return this.car;
};
}
实现类
/**
* @author objcfeng
* @description 宝马建造者
* @date 2020/11/2
*/
public class BmwBuilder extends CarBuilder {
//注意每个给car对象构建组成部分的方法调用的是父类的car对象
@Override
public void buildWheel() {
super.car.setWheel("上好的车轮");
}
@Override
public void buildShell() {
super.car.setShell("宝马外壳");
}
@Override
public void buildEngine() {
super.car.setEngine("宝马产发动机");
}
@Override
public void buildSteeringWheel() {
super.car.setSteeringWheel("有宝马标识的方向盘");
}
//子类不需要实现getCar方法
// @Override
// public Car getCar() {
// return car;
// }
}
其他无需改变。