1、初识建造者模式
建造者模式属于创建型模式。比如说:楼房是千差万别的,楼房的外形,层数,内部房间的数量,房间的装饰都不一样。但是对于建造者来说,抽象出来的建筑流程是确定的。因为建筑一座楼房,都可以归纳为几个步骤:1打桩、2建地基、3搭框架、4内部建设。同理,建造者设计模式也是基于这样的概念而生的,这个设计模式用来解决什么样的情况呢:即流程不变,但每个流程实现的具体细节是会变化的。这样的情况,可以考虑使用建造者。就像盖房子,4个流程都必须有,但每个流程各自的实现细节,各个房子各有不同。建造者模式的好处就是保证了流程不会变化,即流程不会增加也不会遗漏,也不会产生流程次序的错误。而建造者模式,保证了流程的确定性,而流程内部的实现细节,是可继承扩展的。从根源上解决了流程不规范的问题。
撸代码的时候,如果你遇到一个需要把控流程,但流程中的实现细节各有许多的方式,你可以采用建造者模式。用一个director类把控流程,而用许多不同的builder去建造流程中的细节并产生产品。这样,生产出来的产品基本是不会出问题的。因为流程把控好了。你可以有多个builder去负责建造生产产品,而让director去把控流程。如果有新的产品,但是流程一致,你可以再扩张出一个builder来。这样,你看,建造者模式是不是很符合OCP原则呢。
2、建造者模式的概念
将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以有不同的表示。
大概的意思是说:一套的构建过程可以有不同的产品(表示)出来。这些产品(表示)都按照这一套的构建过程被生产出来。
建造者模式通常包括以下这几个角色:
Builder:给出一个抽象接口,规范建造者对于生产的产品的各个组成部分的建造。这个接口只是定一个规范,不涉及具体的建造,具体的建造让继承于它的子类(ConcreteBuilder)去实现
ConcreteBuilder:实现builder接口,针对不同的商业逻辑,具体化各对象部分的建造,最后返回一个建造好的产品。实现抽象类的所有未实现的方法,具体来说一般是两项任务:组建产品;返回组建好的产品。
Director:导演(负责人),顾名思义,负责规范流程之用。在指导中不涉及产品的创建,只负责保证复杂对象各部分被创建或按某种顺序创建。导演类一般不与产品类发生依赖关系,与导演类直接交互的是建造者类。一般来说,导演类被用来封装程序中易变的部分。
Product:复杂对象。
建造者模式的UML图(通过图形来串联自己所学的知识是非常高效的学习方式之一)
3、一个建造者的实例。
汽车的构造当中,包括汽车品牌、型号、价格、产地等等。
复杂对象Product
/**
* 复杂对象Product,这里是汽车
* @author Administrator
*
*/
public class Car {
private String name; //汽车品牌
private String type; //具体的型号
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
抽象的Builder:
/**
* 抽象的构造者
* @author Administrator
*
*/
public interface Builder {
/**
* 一般包含2个部分:1、抽象的建造方法;2:返回建造好的复杂对象
* @param name
*/
void buildName(String name);
void buildType(String type);
Car build();
}
具体的建造者
/**
* 具体的构建者
* @author Administrator
*
*/
public class ConstractBuilder implements Builder{
Car car = new Car();
@Override
public void buildName(String name) {
car.setName(name);
}
@Override
public void buildType(String type) {
car.setType(type);
}
@Override
public Car build() {
return car;
}
}
导演,负责流程规范,在导演类中可以注入建造者对象。
/**
* 导演(负责人)负责流程规范,
* @author Administrator
*
*/
public class Director {
public Car buildCar1(){
ConstractBuilder builder = new ConstractBuilder();
builder.buildName("宝马");
builder.buildType("x6");
return builder.build();
}
public Car buildCar2(){
ConstractBuilder builder = new ConstractBuilder();
builder.buildName("奔驰");
builder.buildType("c200");
return builder.build();
}
}
** 客户端调用**
public class Client {
public static void main(String[] args) {
Director director = new Director(); //创建导演类
//构造对象
Car car1 = director.buildCar1();
Car car2 = director.buildCar2();
System.out.println("car1 name:"+car1.getName()+" type:"+car1.getType());
System.out.println("car2 name:"+car2.getName()+" type:"+car2.getType());
}
}
** 4、使用建造者模式的好处**
- 使用建造者模式可以使客户端不必知道产品内部组成的细节。
- 具体的建造者类之间是相互独立的,对系统的扩展非常有利。
- 由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生任何影响。
5、使用建造者模式的场合
- 创建一些复杂的对象时,这些对象的内部组成构件间的建造顺序是稳定的,但是对象的内部组成构件面临着复杂的变化
- 要创建的复杂对象的算法,独立于该对象的组成部分,也独立于组成部分的装配方法时。