目录
一、建造者模式特点
- 属于创建型模式,是一种将 复杂对象的建造 和 它的表示 分开,使得一样的建造过程可以创造不同的表示。因此,建造对象时只需要指定建造的类型,而不需要关心内部的建造过程。
- 创建型模式的最大的特点就是 链式调用 和 多变的构造方法,后面举例说明。
二、建造者模式结构分析
该模式有四个角色,类图如下:
- Product(产品类):需要被构建的复杂对象;
- Builder(抽象建造者):规范产品的组建,一般是由子类实现具体的过程;
- ConcreteBuilder(具体建造者):实现抽象接口,构建复杂对象;
- Director(指挥者):构造一个使用Builder接口的对象。
注意事项:
- Builder接口中buildPartA()、buildPartB()、buildPartC()的顺序不同,可能会产生不同的结果,需要注意组装时的顺序性;
- 用不同的ConcreteBuilder类构建对象时,会产生不同的结果;
三、举例1 —— 生产不同的包装饮料
- 创建Builder(公共接口,定义通用行为)
public interface DrinkBuilder {
// 生产饮料需要的原材料
void bottleBody(String body);
void water(String water);
void bottleCap(String cap);
void label(String label);
String creatDrink();
}
- 创建ConcreteBuilder1(可口可乐,实现接口父类)
public class BuilderCocaCola implements DrinkBuilder {
// 饮料名称
private String drinkName = "饮料名称为:";
@Override
public void bottleBody(String bodyCocaCola) {
drinkName += bodyCocaCola;
}
@Override
public void water(String waterCocaCola) {
drinkName += waterCocaCola;
}
@Override
public void bottleCap(String capCocaCola) {
drinkName += capCocaCola;
}
@Override
public void label(String labelCocaCola) {
drinkName += labelCocaCola;
}
@Override
public String creatDrink() {
return drinkName;
}
}
- 创建ConcreteBuilder2(旺仔牛奶,实现接口父类)
public class BuilderWWCMilk implements DrinkBuilder {
// 饮料名称
private String drinkName = "饮料名称为:";
@Override
public void bottleBody(String bodyWWCMilk) {
drinkName += bodyWWCMilk;
}
@Override
public void water(String waterWWCMilk) {
drinkName += waterWWCMilk;
}
@Override
public void bottleCap(String capWWCMilk) {
drinkName += capWWCMilk;
}
@Override
public void label(String labelWWCMilk) {
drinkName += labelWWCMilk;
}
@Override
public String creatDrink() {
return drinkName;
}
}
- 创建Director(控制建造过程,按指定顺序构建)
public class DrinkDirector {
// 通过构造器注入
private DrinkBuilder drinkBuilder;
public DrinkDirector(DrinkBuilder drinkBuilder) {
this.drinkBuilder = drinkBuilder;
}
// 控制饮料生产顺序
public void creat(String s1, String s2, String s3, String s4) {
drinkBuilder.bottleBody(s1);
drinkBuilder.water(s2);
drinkBuilder.bottleCap(s3);
drinkBuilder.label(s4);
}
}
- 测试
public class Test1 {
public static void main(String[] args) {
BuilderCocaCola builderCocaCola = new BuilderCocaCola();
DrinkDirector director = new DrinkDirector(builderCocaCola);
director.creat("塑料瓶身-", "碳酸饮料-", "CocaCola盖-", "可口可乐(中国)");
System.out.println("当前" + builderCocaCola.creatDrink());
// 当前饮料名称为:塑料瓶身-碳酸饮料-CocaCola盖-可口可乐(中国)
}
}
public class Test2 {
public static void main(String[] args) {
BuilderWWCMilk builderWWCMilk = new BuilderWWCMilk();
DrinkDirector director1 = new DrinkDirector(builderWWCMilk);
director1.creat("易拉罐瓶身-", "牛奶饮料-", "易拉罐盖-", "旺仔牛奶");
System.out.println("当前" + builderWWCMilk.creatDrink());
// 当前饮料名称为:易拉罐瓶身-牛奶饮料-易拉罐盖-旺仔牛奶
}
}
总结一下:
- 这里得到的结果就是我们需要的 Product(产品类)了;
- 不同Builder实现类接受需要的参数,实现构建对应的产品;
- Director类类似一个指挥所,控制产品内部组装的顺序。
四、举例2 —— 优化:链式调用
实际开发中,常用的是使用建造者模式实现链式调用,这里可以直接讲Builder、Director、Product等省略掉,直接使用ConcreteBuilder,下面对上述过程进行优化:
public class BuilderFanta {
// 饮料名称
private String drinkName = "饮料名称为:";
public BuilderFanta bottleBody(String body) {
drinkName += body;
return this;
}
public BuilderFanta water(String water) {
drinkName += water;
return this;
}
public BuilderFanta bottleCap(String cap) {
drinkName += cap;
return this;
}
public BuilderFanta label(String label) {
drinkName += label;
return this;
}
public String creatDrink() {
return drinkName;
}
}
测试:
public class Test {
public static void main(String[] args) {
BuilderFanta builderFanta = new BuilderFanta();
String name = builderFanta.bottleBody("塑料瓶身-")
.water("碳酸饮料-")
.bottleCap("芬达蓝色盖")
.label("芬达(苹果味)")
.creatDrink();
System.out.println("当前" + name);
}
}
结果:
当前饮料名称为:塑料瓶身-碳酸饮料-芬达蓝色盖芬达(苹果味)
这就是建造者模式了,尤其是链式调用,简洁而美观~,在Mybatis框架中也被大量使用着建造者模式了,感兴趣的可以研究一下Mybatis源码。