1、建造者模式的学习
当创建一个复杂对象时,使用建造者模式可以将对象的构建过程和表示分离开来。它允许使用相同的构建过程来创建不同的表示形式。
建造者模式的主要思想是将一个复杂对象的构建过程分解为一系列简单的步骤,并且使用一个指导者(Director)来逐步指导构建过程。具体的构建过程由一个抽象的建造者(Builder)和具体的建造者(Concrete Builder)来实现。指导者和建造者之间解耦,通过建造者提供的方法来构建对象。
2、建造者模式的使用
题目:
假设你正在开发一个汽车制造系统。汽车有多个组件,包括发动机、底盘、车身和内饰等。使用建造者模式来实现一个汽车制造器,该制造器能够根据用户的选择来构建不同类型的汽车。
实现
定义一个汽车类(Car),包括发动机(engine)、底盘(chassis)、车身(body)和内饰(interior)等属性,并提供相应的设置方法。
定义一个汽车建造者接口(CarBuilder),包括设置发动机、底盘、车身和内饰等方法,以及获取最终构建的汽车对象的方法。
实现两个具体的汽车建造者类,分别用于构建高级车型(LuxuryCarBuilder)和普通车型(StandardCarBuilder)的汽车。每个建造者类都实现了 CarBuilder 接口,根据不同车型的要求设置相应的属性。
定义一个指挥者类(CarManufacturer),用于指导汽车的构建流程。该类包含一个构建器成员变量,可以接受不同的建造者对象,并提供一个构建汽车的方法。
在客户端代码中,使用建造者模式构建两辆不同类型的汽车,并展示其属性信息。
代码
/**
* @Author: myf
* @CreateTime: 2023-05-17 21:16
* @Description: Car产品
*/
@Data
public class Car {
private String engine;
private String chassis;
private String body;
private String interior;
@Override
public String toString() {
return "Car is done " +
"engine='" + engine + '\'' +
", chassis='" + chassis + '\'' +
", body='" + body + '\'' +
", interior='" + interior + '\'';
}
}
/**
* @Author: myf
* @CreateTime: 2023-05-17 21:18
* @Description: 抽象汽车构建者
*/
public abstract class CarBuilder {
protected Car car = new Car();
/**
* 发动机
*/
abstract void setEngine();
/**
* 底盘
*/
abstract void setChassis();
/**
* 车体
*/
abstract void setBody();
/**
* 内饰
*/
abstract void setInterior();
/**
* 构建汽车对象
*
* @return
*/
Car build() {
return car;
}
}
/**
* @Author: myf
* @CreateTime: 2023-05-17 21:23
* @Description: LuxuryCarBuilder 具体的汽车构建者,高级汽车。
*/
public class LuxuryCarBuilder extends CarBuilder {
@Override
public void setEngine() {
super.car.setEngine("super engine");
}
@Override
public void setChassis() {
super.car.setChassis("super chassis");
}
@Override
public void setBody() {
super.car.setBody("super body");
}
@Override
public void setInterior() {
super.car.setInterior("super interior");
}
}
/**
* @Author: myf
* @CreateTime: 2023-05-17 21:25
* @Description: StandardCarBuilder 具体的汽车构建者,普通汽车。
*/
public class StandardCarBuilder extends CarBuilder {
@Override
void setEngine() {
super.car.setEngine("standar engine");
}
@Override
void setChassis() {
super.car.setChassis("chassis");
}
@Override
void setBody() {
super.car.setBody("body");
}
@Override
void setInterior() {
super.car.setInterior("interior");
}
}
/**
* @Author: myf
* @CreateTime: 2023-05-17 21:26
* @Description: CarManufacturer 汽车构建的指挥者
*/
public class CarManufacturer {
public Car build(CarBuilder carBuilder) {
carBuilder.setBody();
carBuilder.setChassis();
carBuilder.setEngine();
carBuilder.setInterior();
return carBuilder.build();
}
}
public class CarClient {
public static void main(String[] args) {
CarManufacturer carManufacturer = new CarManufacturer();
System.out.println(carManufacturer.build(new LuxuryCarBuilder()).toString());
CarManufacturer standardCarManufacturer = new CarManufacturer();
System.out.println(standardCarManufacturer.build(new StandardCarBuilder()).toString());
}
}
执行结果
Car is done engine='super engine', chassis='super chassis', body='super body', interior='super interior'
Car is done engine='standar engine', chassis='chassis', body='body', interior='interior'
以上是一个传统型的建造者模式,在这个模式中,我们无法指定车的这些属性的具体值,在简化版的建造者模式中需要我们自己指定具体的属性。下面是简化版的建造者模式(省去了指导者)。
@Getter
public class Car {
private String engine;
private String chassis;
private String body;
private String interior;
private Car(Builder builder) {
this.body = builder.getBody();
this.chassis = builder.getChassis();
this.engine = builder.getEngine();
this.interior = builder.getInterior();
}
public static Builder builder() {
return new Builder();
}
@Getter
public static final class Builder {
private String engine;
private String chassis;
private String body;
private String interior;
public Builder engine(String engine) {
this.engine = engine;
return this;
}
public Builder chassis(String chassis) {
this.chassis = chassis;
return this;
}
public Builder body(String body) {
this.body = body;
return this;
}
public Builder interior(String interior) {
this.interior = interior;
return this;
}
public Car build() {
return new Car(this);
}
}
@Override
public String toString() {
return "Car is done " +
"engine='" + engine + '\'' +
", chassis='" + chassis + '\'' +
", body='" + body + '\'' +
", interior='" + interior + '\'';
}
}
使用
public class CarClinet {
public static void main(String[] args) {
System.out.println(
Car.builder().chassis("chaghgssis").body("body").engine("engine")
.interior("interior").build()
);
}
}
结果
Car is done engine='engine', chassis='chaghgssis', body='body', interior='interior'
所以当我们需要生产一个产品的属性比较固定可以使用传统建造者模式来实现;当产品的属性不太固定时,就更适合使用简化版建造者模式来实现。
3、和抽象工厂模式的区别
之前写的抽象工厂模式;抽象工厂模式更关心的是一组产品的生产,而建造者模式关心的是一个复杂产品的属性的构建过程。比如上面是使用了传统的建造者来实现的,下面我们结合抽象工厂模式来实现一下.大家应该就能更清楚区别了。
抽象的汽车工厂,负责生产一组汽车
public interface CarFactory {
/**
* 高级汽车
*
* @return
*/
Car luxuryCar();
/**
* 普通汽车
*
* @return
*/
Car standardCar();
}
具体的汽车生产工厂,在具体的汽车生产的时候就会涉及到汽车的各个属性,在这里我们就用建造者模式来构建汽车的各个属性,和上面的代码结合起来了
public class CarFactoryImpl implements CarFactory{
@Override
public Car luxuryCar() {
CarManufacturer carManufacturer = new CarManufacturer();
return carManufacturer.build(new LuxuryCarBuilder());
}
@Override
public Car standardCar() {
CarManufacturer carManufacturer = new CarManufacturer();
return carManufacturer.build(new StandardCarBuilder());
}
}
结果
public class CarClient {
public static void main(String[] args) {
CarManufacturer carManufacturer = new CarManufacturer();
System.out.println(carManufacturer.build(new LuxuryCarBuilder()).toString());
CarManufacturer standardCarManufacturer = new CarManufacturer();
System.out.println(standardCarManufacturer.build(new StandardCarBuilder()).toString());
CarFactory carFactory = new CarFactoryImpl();
System.out.println(carFactory.luxuryCar());
System.out.println(carFactory.standardCar());
}
}
Car is done engine='super engine', chassis='super chassis', body='super body', interior='super interior'
Car is done engine='standar engine', chassis='chassis', body='body', interior='interior'
Car is done engine='super engine', chassis='super chassis', body='super body', interior='super interior'
Car is done engine='standar engine', chassis='chassis', body='body', interior='interior'
到这里大家应该清楚就建造者模式和抽象工厂模式的区别了吧。建造者模式关心的是一个产品的属性构建过程;抽象工厂模式关心的是一组产品的生产