上期回顾:抽象工厂模式
一、建造者模式定义
建造者模式是设计模式的一种,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
二、角色
在这样的设计模式中,有以下几个角色:
1、builder
:为创建一个产品对象的各个部件指定抽象接口。
2、ConcreteBuilder
:实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并提供一个检索产品的接口。
3、Director
:构造一个使用Builder接口的对象。
4、Product
:表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
三、案例
建造者模式其实并不复杂,实际上就是将产品(复杂对象)由多个零件进行组装的过程。结合一个案例深入了解。
现在有一个车厂,里面有个老板(Director),负责指挥员工组装一辆汽车(Product)。员工实际将汽车的各个零件组装成汽车的过程(ConcreteBuilder)实现了定义产品组装过程这一抽象接口(builder)。
(一)定义产品(Product):汽车
class Car{
private String engine; //发动机
private String chassis; //底盘
private String body; //车身
public String getEngine() {
return engine;
}
public void setEngine(String engine) {
this.engine = engine;
}
public String getChassis() {
return chassis;
}
public void setChassis(String chassis) {
this.chassis = chassis;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
}
(二)定义抽象汽车组装过程(builder)
abstract class Builder {
protected Car car = new Car();
//组装发动机
public abstract void bulidEngine();
//组装底盘
public abstract void bulidChassis();
//组装车身
public abstract void bulidBody();
//最终得到组装好的产品
public abstract Car createCar();
}
这个过程定义了四个组装零件的抽象方法,既然是抽象方法,那么肯定有对应的实现类,就是接下来的ConcreteBuilder。
(三)员工实际将汽车的各个零件组装成汽车的过程(ConcreteBuilder)
假设有两种具体产品的装配过程:奥迪、宝马
//组装奥迪车的过程
class AudiBuilder extends Builder {
@Override
public void bulidEngine() {
car.setEngine("1.4升涡轮增压发动机");
}
@Override
public void bulidChassis() {
car.setChassis("土豪金底盘");
}
@Override
public void bulidBody() {
car.setBody("白银车身");
}
@Override
public Car createCar() {
return car;
}
}
//组装宝马的过程
class BmwBuilder extends Builder {
@Override
public void bulidEngine() {
car.setEngine("2.0升涡轮增压发动机");
}
@Override
public void bulidChassis() {
car.setChassis("黑色底盘");
}
@Override
public void bulidBody() {
car.setBody("金色车身");
}
@Override
public Car createCar() {
return car;
}
}
ConcreteBuilder实现了组装零件的具体过程,至于什么零件,这里看个乐子就行~
(四)指挥者,指挥员工组装零件(Director)
//指挥者
public class CarDirector {
//指定建造产品的类型
private Builder builder;
public CarDirector(Builder builder){}{
this.builder= builder;
}
//组装
public Car construct(){
builder.bulidEngine();
builder.bulidChassis();
builder.bulidBody();
return builder.createCar();
}
}
(五)测试:当有客户来买奥迪车这一过程
public class Customer {
public static void main(String[] args) {
//遇见了车厂的老板和员工
//决定组装的是奥迪汽车
CarDirector carDirector = new CarDirector(new AudiBuilder());
//老板开始指挥员工组装汽车
Car car = carDirector.construct();
System.out.println(car.toString());
}
}
运行结果:
如果想要组装宝马呢?
改一下组装对象过程即可
运行结果:
四、特殊:合并指挥者和建造者
Director在建造者模式中是负责知道具体建造者如何组装产品的的角色。在它的类中,制定了组装零件的顺序,并最终返回一个完整的复杂产品。但是某情况可以省略指挥者。例如在具体建造者只有一个的情况下,如果抽象建造者角色已经被省略掉,那么还可以省略掉指导者角色,让Builder自己扮演指导者和建造者双重角色。把上面的代码调整下就是:
}
//抽象builder类
abstract class Builder2{
private Car car = new Car();
public abstract void bulidEngine();
public abstract void bulidChassis();
public abstract void bulidBody();
public Car construct(){
this.bulidEngine();
this.bulidChassis();
this.bulidBody();
return this.createCar();
}
}
我们发现,修改后的Builder将原本由指挥者负责指挥员工组装零件,变成了建造者自己打造零件并组装。这样也是可以的。
五、总结
在建造者模式中,客户不用知道复杂产品的组装过程,将产品本身与产品的创建过程解耦,使得相同的创建过程可以得到不同的产品对象。实际上这很像是抽象工厂模式,比如抽象Builder就很像一个抽象工厂,而产品组装的具体实现也可以看做是具体工厂。但是这两种设计模式也是有很大区别的,例如抽象工厂模式是针对的是多个产品族结构的,一个产品族内有多个产品系列,而建造者模式只是针对某一复杂的产品的,最终得到一个组装好的产品。所以说建造者模式更适合复杂的产品构建。