一:简介
建造者模式可以将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以有不同的表示。
二:角色
- Product:表示被构造的复杂对象。
- Builder:给出一个抽象接口,以规范产品对象的各个组成成分的建造。这个接口规定要实现复杂对象的哪些部分的创建,并不涉及具体的对象部件的创建。
- ConcreteBuilder:实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并提供一个检索产品的接口。
- Director:构造一个使用Builder接口的对象,指导构建过程。
三:建造者模式
1.创建Product:
我们定义一个基类Car;车有启动,停止,和鸣笛。run方法为车的运动过程,不同的车,运动过程不同。根据传入的list来判断调用顺序。
public abstract class Car {
List<String> types = new ArrayList<String>();
/**
* 启动
*/
public abstract void start();
/**
* 停止
*/
public abstract void stop();
/**
* 喇叭叫
*/
public abstract void alram();
/**
* 汽车动
* 为了体现创建者模式 同样的构建过程有不同的表示,我们通过传入标识来执行相应的方法
*/
public void run(){
for (int i = 0; i < types.size(); i++){
String type = types.get(i);
if (type != null) {
if ("start".equals(type)) {
start();
} else if ("stop".equals(type)) {
stop();
} else if ("alram".equals(type)) {
alram();
}
}
}
}
public void setTypes(List<String> types) {
this.types = types;
}
}
2.创建具体的产品:
宝马车和奔驰车
public class BMCar extends Car {
@Override
public void start() {
System.out.println("宝马车启动了");
}
@Override
public void stop() {
System.out.println("宝马车停止了");
}
@Override
public void alram() {
System.out.println("宝马车按了按喇叭叫了");
}
}
public class BZCar extends Car {
@Override
public void start() {
System.out.println("奔驰车启动了");
}
@Override
public void stop() {
System.out.println("奔驰车停止了");
}
@Override
public void alram() {
System.out.println("奔驰车按了按喇叭叫了");
}
}
3.创建Builder接口:
我们只需提供启动顺序,和车即可
public interface CarBuilder {
/**
* 设置车的启动顺序
* @param types
*/
public abstract void setType(List<String> types);
/**
* 获得相应的车
* @return
*/
public abstract Car getCar();
}
4.创建Builder的具体实现类:
我们有宝马车和奔驰车
public class BMBuilder implements CarBuilder {
BMCar bmCar;
public BMBuilder() {
bmCar = new BMCar();
}
@Override
public void setType(List<String> types) {
bmCar.setTypes(types);
}
@Override
public Car getCar() {
return bmCar;
}
}
public class BZBuilder implements CarBuilder {
BZCar bzCar;
public BZBuilder() {
bzCar = new BZCar();
}
@Override
public void setType(List<String> types) {
bzCar.setTypes(types);
}
@Override
public Car getCar() {
return bzCar;
}
}
5.创建Director:
Director也是导演的意思,提供了车的构造者,并且规定车的启动顺序。
public class CarDirector {
private List<String> types = new ArrayList<String>();
private BMBuilder bmBuilder = new BMBuilder();
private BZBuilder bzBuilder = new BZBuilder();
/**
* 奔驰车
* @return
*/
public BZCar getBZCar(){
//注意这里需要先clear
this.types.clear();
//执行属性
types.add("start");//先启动
types.add("alram");//在按喇叭
types.add("stop");//跑一段时间后没油了,就停了。
bzBuilder.setType(types);
return (BZCar) bzBuilder.getCar();
}
/**
* 1号场生产的宝马车
* @return
*/
public BMCar getBMCar1(){
//注意这里需要先clear
this.types.clear();
//执行属性
types.add("start");//先启动
types.add("alram");//在按喇叭
//宝马车比较牛逼,启动了就不停了
bmBuilder.setType(types);
return (BMCar) bmBuilder.getCar();
}
/**
* 2号场生产的宝马车
* @return
*/
public BMCar getBMCar2(){
//注意这里需要先clear
this.types.clear();
//执行属性
types.add("start");//先启动
types.add("alram");//在按喇叭
types.add("stop");
bmBuilder.setType(types);
return (BMCar) bmBuilder.getCar();
}
}
在这个CarDirector (导演类)中我们发现,车的构造通过builder对象生成的,而车的具体表示则是由我们的CarDirector规定,这就是我们的构造者模式‘’复杂对象构建与它的表示分离的体现‘’。
又为了体现‘’同样的构建过程有不同的表示‘’我们宝马车有两种生产的厂家。1号生产出来的车它能启动并且按喇叭,但它开了以后不能停。2号车则能停下来。这也就验证了同样的一辆宝马车,它的表示却不一样。
6.测试类:
public class Client {
public static void main(String[] args) {
CarDirector carDirector = new CarDirector();
carDirector.getBMCar1().run();
System.out.println("-------------------------------------");
carDirector.getBMCar2().run();
System.out.println("-------------------------------------");
carDirector.getBZCar().run();
}
}
结果:
宝马车启动了
宝马车按了按喇叭叫了
-------------------------------------
宝马车启动了
宝马车按了按喇叭叫了
宝马车停止了
-------------------------------------
奔驰车启动了
奔驰车按了按喇叭叫了
奔驰车停止了
结果也是我们预想之中的。有了导演类之后,我们客户端的调用就一目了然了。因为我们不需要去设置具体方法的顺序。
四:总结
建造者模式和工厂模式还是挺像的。但是他们的区别是,建造者模式的主要能是基本方法的调用顺序,这些方法已经被我们实现了。而工厂模式强调的是创建,要什么我们就创建什么,具体的组装顺序不关心。
五:适用场景
当一个产品类非常复杂或者产品类中的调用顺序不同产生了不同的效能。这时我们就可以用建造者模式。