跟着《软件秘笈---设计模式那点事》学习
定义:
我觉得最容易让人接受的定义来自百度百科:将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。
角色:
1 builder:为创建一个产品对象的各个部件指定抽象接口。
2 ConcreteBuilder:实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并 提供一个检索产品的接口。
3 Director:构造一个使用Builder接口的对象。(指导者)
4 Product:表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
类图:
实例:
一个去营业厅办套餐的例子
简便起见我把目录结构去了,但其中一个包内继承的限制也很有用。
/*
* POJO手机套餐
* */
public class MobilePackage {
// 话费
private double money;
// 短信
private double message;
// 彩铃
private String music;
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
public double getMessage() {
return message;
}
public void setMessage(double message) {
this.message = message;
}
public String getMusic() {
return music;
}
public void setMusic(String music) {
this.music = music;
}
}
/*
* 就是这样让创建对象和表现对象相分离
* */
public interface IMobileBuilder {
public void buildMoney();
public void buildMessage();
public void buildMusic();
public MobilePackage getMobilePackage();
}
/*
* 抽象建造者
* */
public abstract class AbstractBasePackage {
//在不同包的子类下使用
protected MobilePackage mobilePackage;
public AbstractBasePackage(){
this.mobilePackage = new MobilePackage();
}
}
具体创建者
/*
* 每一个建造者都含有一个产品的实例
* */
public class MobileBuilderImpl_1 extends AbstractBasePackage implements
IMobileBuilder {
@Override
public void buildMoney() {
this.mobilePackage.setMoney(20.0D);
}
@Override
public void buildMessage() {
this.mobilePackage.setMessage(400D);
}
@Override
public void buildMusic() {
this.mobilePackage.setMusic("红尘客栈");
}
@Override
public MobilePackage getMobilePackage() {
return this.mobilePackage;
}
}
/*
* 每一个建造者都含有一个产品的实例
* */
public class MobileBuilderImpl_2 extends AbstractBasePackage implements
IMobileBuilder {
@Override
public void buildMoney() {
this.mobilePackage.setMoney(30.0D);
}
@Override
public void buildMessage() {
this.mobilePackage.setMessage(600D);
}
@Override
public void buildMusic() {
this.mobilePackage.setMusic("黑色幽默");
}
@Override
public MobilePackage getMobilePackage() {
return this.mobilePackage;
}
}
创建指导者
public class MoblieDirector {
public MobilePackage createMobilePackage(IMobileBuilder mobileBuilder){
if(mobileBuilder != null){
mobileBuilder.buildMoney();
mobileBuilder.buildMessage();
mobileBuilder.buildMusic();
return mobileBuilder.getMobilePackage();
}
return null;
}
}
MainApp
public class MainApp {
public static void main(String[] args) {
MoblieDirector moblieDirector = new MoblieDirector();
MobileBuilderImpl_1 mobileBuilderImpl_1 = new MobileBuilderImpl_1();
MobileBuilderImpl_2 mobileBuilderImpl_2 = new MobileBuilderImpl_2();
printMessage(moblieDirector.createMobilePackage(mobileBuilderImpl_1));
printMessage(moblieDirector.createMobilePackage(mobileBuilderImpl_2));
}
private static void printMessage(MobilePackage mobilePackage) {
System.out.println("--话费:" + mobilePackage.getMoney() + ", \t\t 短信:"
+ mobilePackage.getMessage() + "条, \t\t 彩铃:"
+ mobilePackage.getMusic());
}
}
分析:
指导者是这个关键,他让整个代码干净利落,思路清晰,维护成本大大降低。
但指导者是可以省略的,模式本身要理解的是创建者,它相当于把零件组装起来,然后提供产品。
具体做法是,创建者持有产品的引用,在创建者中先构件产品,再表示产品,当然创建者和产品都是经过抽象的。
建造者模式是单一职责原则的体现
使用场合:
1 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
2 当构造过程必须允许被构造的对象有不同表示时。
一句话总结:
将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示。
Java SDK中的建造者模式
java.lang.StringBuilder(线程安全)
java.lang.StringBuffer(线程不安全)