创建型模式:关注对象的创建过程,它描述如何将对象的创建、使用分离,让用户无需关心对象的创建细节,从而降低系统的耦合度,让设计方案易于修改、扩展。
一、概述
建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
二、结构
- Builder(抽象建造者):
- ConcreteBuilder(具体建造者):
- Product(产品):
- Director(指挥者):
三、举例实现
实例代码: Product(产品):
public class Car {
private String engine;
private String wheel;
private String accelerator;
private String clutch;
private String shiftGear;
private String breakSys;
private String shell;
private String fuelTank;
private String seat;
}
Builder(抽象建造者):
public abstract class CarBuilder {
protected Car car = new Car();
public abstract void buildEngine();
public abstract void buildWheel();
public abstract void buildAccelerator();
public abstract void buildClutch();
public abstract void buildShiftGear();
public abstract void buildBreakSys();
public abstract void buildShell();
public abstract void buildFuelTank();
public abstract void buildSeat();
public Car getWholeCar(){
return car;
}
}
ConcreteBuilder(具体建造者):
public class ConcreteCarBuilder extends CarBuilder {
@Override
public void buildEngine() {
car.setEngine("高质量引擎");
}
@Override
public void buildWheel(){
car.setWheel("耐磨防滑轮胎");
}
@Override
public void buildAccelerator(){
car.setAccelerator("加速优秀油门");
}
@Override
public void buildClutch(){
car.setClutch("优质离合器");
}
@Override
public void buildShiftGear(){
car.setShiftGear("高精度变速箱");
}
@Override
public void buildBreakSys(){
car.setBreakSys("快速刹车系统");
}
@Override
public void buildShell(){
car.setbuildShell("高抗外壳");
}
@Override
public void buildFuelTank(){
car.setFuelTank("耐高温燃油箱");
}
@Override
public void buildSeat(){
car.setSeat("优质皮草座椅");
}
Director(指挥者):
public class CarAssembler{
private CarBuilder builder;
public CarAssembler(CarBuilder builder){
this.builder = builder;
}
public Product construct(){
builder.buildEngine();
builder.buildWheel();
builder.buildAccelerator();
builder.buildClutch();
builder.buildShiftGear();
builder.buildBreakSys();
builder.buildShell();
builder.buildFuelTank();
builder.buildSeat();
return builder.getWholeCar();
}
}
四、讨论:指挥者类
指挥者类 Director 类十分重要,简单的 Director 类用于指导具体建造者如何构建产品,依次调用buildePartX() 方法,控制调用先后次序后返回完整对象。
1、省略 Director 类
为了简化系统结构,可将 Director 和 抽象建造者合并,提供逐步构建复杂产品对象的 construct() 方法。一般在抽象 Builder 类中,将该方法定义为静态 (static) 方法,便于直接调用。
传参的construct方法:
public abstract class CarBuilder{
protected static Car car = new Car();
public abstract void buildEngine();
public abstract void buildWheel();
public abstract void buildAccelerator();
public abstract void buildClutch();
public abstract void buildShiftGear();
public abstract void buildBreakSys();
public abstract void buildShell();
public abstract void buildFuelTank();
public abstract void buildSeat();
public static Car construct(CarBuilder builder){
builder.buildEngine();
builder.buildWheel();
builder.buildAccelerator();
builder.buildClutch();
builder.buildShiftGear();
builder.buildBreakSys();
builder.buildShell();
builder.buildFuelTank();
builder.buildSeat();
return car;
}
}
无参的construct方法:
public abstract class CarBuilder{
protected static Car car = new Car();
public abstract void buildEngine();
public abstract void buildWheel();
public abstract void buildAccelerator();
public abstract void buildClutch();
public abstract void buildShiftGear();
public abstract void buildBreakSys();
public abstract void buildShell();
public abstract void buildFuelTank();
public abstract void buildSeat();
public static Car construct(){
this.buildEngine();
this.buildWheel();
this.buildAccelerator();
this.buildClutch();
this.buildShiftGear();
this.buildBreakSys();
this.buildShell();
this.buildFuelTank();
this.buildSeat();
return car;
}
}
这里,construct() 方法定义了 buildPartX() 方法的调用次序,并为此提供了标准流程,类似于模板方法模式。
这种方式不影响可扩展性,简化了结构,但加重了建造者的职责,为更符合单一职责原则,大多数情况下并不推荐这样做。
2、引入钩子方法
建造者模式可以通过 Director 类更加精细地控制产品的创建过程,例如增加一类称为钩子方法(Hook Method) 的特殊方法来控制是否对某个buildPartX() 进行调用。
钩子方法的返回值为 boolean 类型,方法名一般为isXXX(),钩子方法定义在 抽象 Builder 类 中。
public abstract class CarBuilder{
protected static Car car = new Car();
public abstract void buildEngine();
public abstract void buildWheel();
public abstract void buildAccelerator();
public abstract void buildClutch();
public abstract void buildShiftGear();
public abstract void buildBreakSys();
public abstract void buildShell();
public abstract void buildFuelTank();
public abstract void buildSeat();
public boolean isMotor(){
return false;
}
public Car createCar(){
return car;
}
}
public class ConcreteCarBuilder extends CarBuilder {
@Override
public void buildEngine() {
car.setEngine("高质量引擎");
}
@Override
public void buildWheel(){
car.setWheel("耐磨防滑轮胎");
}
@Override
public void buildAccelerator(){
car.setAccelerator("加速优秀油门");
}
@Override
public void buildClutch(){
car.setClutch("优质离合器");
}
@Override
public void buildShiftGear(){
car.setShiftGear("高精度变速箱");
}
@Override
public void buildBreakSys(){
car.setBreakSys("快速刹车系统");
}
@Override
public void buildShell(){
car.setbuildShell("高抗外壳");
}
@Override
public void buildFuelTank(){
car.setFuelTank("耐高温燃油箱");
}
@Override
public void buildSeat(){
car.setSeat("优质皮草座椅");
}
@Override
public boolean isMotor(){
return true;
}
}
public class CarAssembler{
public Product construct(CarBuilder builder){
builder.buildWheel();
builder.buildAccelerator();
builder.buildShiftGear();
builder.buildBreakSys();
builder.buildShell();
if(!builder.isMotor()){
builder.buildClutch();
builder.buildEngine();
builder.buildFuelTank();
}
builder.buildSeat();
return builder.getWholeCar();
}
}
五、灵活建造者
灵活的建造者模式被广泛地应用在Spring 框架中,灵活的建造者模式去除了指挥者类,使得用户可以参与到对象的构建过程中,但是要求用户本身对构建对象的方法有一定了解。
实例代码: Product(产品):
public class Car {
private String engine;
private String wheel;
private String accelerator;
private String clutch;
private String shiftGear;
private String breakSys;
private String shell;
private String fuelTank;
private String seat;
}
ConcreteBuilder(具体建造者):
public class CarBuilder {
protected Car car = new Car();
public CarBuilder buildEngine(String text) {
car.setEngine(text);
return this;
}
public CarBuilder buildWheel(String text) {
car.setWheel(text);
return this;
}
public CarBuilder buildAccelerator(String text) {
car.setAccelerator(text);
return this;
}
public CarBuilder buildClutch(String text) {
car.setClutch(text);
return this;
}
public CarBuilder buildShiftGear(String text) {
car.setShiftGear(text);
return this;
}
public CarBuilder buildBreakSys(String text) {
car.setBreakSys(text);
return this;
}
public CarBuilder buildShell(String text) {
car.setShell(text);
return this;
}
public CarBuilder buildFuelTank(String text) {
car.setFuelTank(text);
return this;
}
public CarBuilder buildSeat(String text) {
car.setSeat(text);
return this;
}
public Car build(){
return car;
}
}
测试代码:
Car car = new CarBuilder()
.buildAccelerator("加速优秀油门")
.buildBreakSys("快速刹车系统")
.buildClutch("优质离合器")
.buildEngine("高质量引擎")
.buildFuelTank("耐高温燃油箱")
.buildSeat("优质皮草座椅")
.buildShell("高抗外壳")
.buildShiftGear("高精度变速箱")
.buildWheel("耐磨防滑轮胎")
.build();
System.out.println(car);
六、特点
? 优点
- 建造者模式中,用户无需关心产品内部组成细节,将产品与本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。如有需要,可以将创建过程暴露给用户,使得对象的创建更加灵活,但这对用户提出了更高的要求。
- 每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的建造者,用户使用不同的具体建造者就可得到不同的产对象。增加新的建造者无需修改原有类库代码,系统扩展方便,符合开闭原则。
- 可以更加精细的控制产品创建过程,创建思路更加清晰。
? 缺点
- 建造者模式创建产品具有较多共同点,其组成 成分相似,如若两对象组成部分相差过大,使用会受限。
- 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统很庞大。
|