什么是建造者模式
建造者模式( Builder Pattern )是设计模式的一种,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
实用范围:
- 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
- 当构造过程必须允许被构造的对象有不同表示时。
设计模式和编程语言无关,但是二当家的依然用Java语言去实战举例。
建造者模式中的角色
- Builder:为创建一个产品对象的各个部件指定抽象接口。
- ConcreteBuilder:实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并提供一个检索产品的接口。
- Director:构造一个使用Builder接口的对象。
- Product:表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
产品角色(Product)
我们用汽车作为产品角色(Product)。我们这里的车包含车身,引擎和动力源(真实的车当然不仅包含这些零件),车身必须有,没有车身根本不能称之为车。
package com.secondgod.builder;
import java.text.MessageFormat;
/**
* 汽车
*
* @author 二当家的白帽子 https://le-yi.blog.csdn.net/
*/
public class Car {
/**
* 车身(必须有)
*/
private final String body;
/**
* 引擎
*/
private String engine;
/**
* 动力源
*/
private String energy;
public Car(String body) {
this.body = body;
}
public String getBody() {
return body;
}
public String getEngine() {
return engine;
}
public void setEngine(String engine) {
this.engine = engine;
}
public String getEnergy() {
return energy;
}
public void setEnergy(String energy) {
this.energy = energy;
}
public String toString() {
return MessageFormat.format("在[{0}]车身上配备有[{1}]引擎和[{2}]动力源的汽车", body, engine, energy);
}
}
抽象建造者(Builder)
我们用汽车生产线接口作为抽象建造者角色(Builder)。声明出汽车生产线应该有的方法。这里我们仅仅包含建造车身,建造引擎,建造动力源的方法,对应车的配件,还有一个取车的方法用来将造好的车从生产线上取下来。
package com.secondgod.builder;
/**
* 汽车生产线
*
* @author 二当家的白帽子 https://le-yi.blog.csdn.net/
*/
public interface ICarBuilder {
/**
* 建造车身
*/
void buildBody();
/**
* 建造引擎
*/
void buildEngine();
/**
* 建造动力源
*/
void buildEnergy();
/**
* 取车
* @return
*/
Car retrieveCar();
}
具体建造者角色(ConcreteBuilder)
我们用燃油车生产线和电动车生产线作为具体建造者角色(ConcreteBuilder)。这里有一个细节,由于车身是必须有的,所以必须先建造车身。
package com.secondgod.builder;
/**
* 燃油车生产线
*
* @author 二当家的白帽子 https://le-yi.blog.csdn.net/
*/
public class GasolineCarBuilder implements ICarBuilder {
private Car car;
@Override
public void buildBody() {
car = new Car("燃油");
}
@Override
public void buildEngine() {
car.setEngine("燃油发动机");
}
@Override
public void buildEnergy() {
car.setEnergy("汽油油箱");
}
@Override
public Car retrieveCar() {
Car retrieveCar = car;
car = null;
return retrieveCar;
}
}
package com.secondgod.builder;
/**
* 电动车生产线
*
* @author 二当家的白帽子 https://le-yi.blog.csdn.net/
*/
public class ElectricCarBuilder implements ICarBuilder{
private Car car;
@Override
public void buildBody() {
car = new Car("电动");
}
@Override
public void buildEngine() {
car.setEngine("电驱动系统");
}
@Override
public void buildEnergy() {
car.setEnergy("新能源电池");
}
@Override
public Car retrieveCar() {
Car retrieveCar = car;
car = null;
return retrieveCar;
}
}
导演者角色(Director)
我们用汽车工程师作为导演者角色(Director)。他知道怎么操作生产线(对不起,我们的生产线不是全自动的)。
package com.secondgod.builder;
/**
* 汽车工程师
*
* @author 二当家的白帽子 https://le-yi.blog.csdn.net/
*/
public class CarEngineer {
/**
* 构建汽车
*
* @param builder
* @return
*/
public Car constructCar(ICarBuilder builder) {
builder.buildBody();
builder.buildEngine();
builder.buildEnergy();
return builder.retrieveCar();
}
}
最终测试
package com.secondgod.builder;
public class Test {
public static void main(String[] args) {
// 一个工程师
CarEngineer carEngineer = new CarEngineer();
// 两条生产线
ICarBuilder gasolineCarBuilder = new GasolineCarBuilder();
ICarBuilder electricCarBuilder = new ElectricCarBuilder();
// 一天造两辆
Car gasolineCar = carEngineer.constructCar(gasolineCarBuilder);
Car electricCar = carEngineer.constructCar(electricCarBuilder);
// 够生活了
System.out.println(gasolineCar);
System.out.println(electricCar);
}
}
和我们的预期一致,Nice。
尾声
建造者模式经常使用变形,可以把抽象建造者角色,具体建造者和导演者角色合并到一起,比如StringBuilder这个JDK自带的类就是这样。
非常感谢你阅读本文~
放弃不难,但坚持一定很酷~
希望我们大家都能每天进步一点点~
本文由 二当家的白帽子:https://developer.aliyun.com/profile/sqd6avc7qgj7y 博客原创~