类图
定义
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
优点
- 封装性 使用建造者模式可使客户端不必知道产品内部组成的细节
- 建造者独立,容易扩展
- 便于控制细节风险 由于具体的建造者是独立的,因此可对建造过程逐步细化,而不对其它模块产生影响
使用场景
- 相同的方法,不同的执行顺序,产生不同的事件结果时
- 多个部件或零件,都可以装配到一个对象中,但产生的运行结果又不相同时
- 产品类非常复杂,或者产品类中的调用顺序不同产生不同的效能
注意事项
建造者模式与工厂模式虽同为创建类模式,但注重点不同,建造者模式最重要的功能是基本方法的调用顺序安排,即这些基本方法已经实现了,只是零件的装配,顺序不同产生的对象也不同,而工厂方法则重点是创建,组装顺序不是它关心的
产品类
public class Product {
/**
* 产品信息
*/
private String info = "";
/**
* 添加信息
*
* @param part 功能
*/
public void addPart(String part) {
info += part + ";";
}
public void doSomething() {
// 独立业务处理
System.out.println("Product 我的功能:" + info);
}
}
抽象建造者
public abstract class Builder {
/**
* 设置产品的不同部分,以获得不同的产品
*/
public abstract void setPart1();
public abstract void setPart2();
public abstract void setPart3();
/**
* 建造产品
*/
public abstract Product builderProduct();
}
具体建造者
public class ConcreteBuilder extends Builder {
private Product product = new Product();
@Override
public void setPart1() {
product.addPart("功能1");
System.out.println("产品需要功能1");
}
@Override
public void setPart2() {
product.addPart("功能2");
System.out.println("产品需要功能2");
}
@Override
public void setPart3() {
product.addPart("功能3");
System.out.println("产品需要功能3");
}
@Override
public Product builderProduct() {
System.out.println("建造者建造产品");
return product;
}
}
导演类
public class Director {
private Builder builder = new ConcreteBuilder();
/**
* 构建A产品,A产品需要功能1和功能2
*
* @return A产品
*/
public Product getAProduct() {
// 构建不同的产品
builder.setPart1();
builder.setPart2();
return builder.builderProduct();
}
/**
* 构建B产品,B产品需要功能2和功能3
*
* @return B产品
*/
public Product getBProduct() {
// 构建不同的产品
builder.setPart2();
builder.setPart3();
return builder.builderProduct();
}
}
场景类
public class Client {
public static void main(String[] args) {
//创建导演类
Director director1 = new Director();
//建造A产品
Product productA = director1.getAProduct();
productA.doSomething();
//创建导演类
Director director2 = new Director();
//建造B产品
Product productB = director2.getBProduct();
productB.doSomething();
}
}
运行结果
产品需要功能1
产品需要功能2
建造者建造产品
Product 我的功能:功能1;功能2;
产品需要功能2
产品需要功能3
建造者建造产品
Product 我的功能:功能2;功能3;
不过我们一般项目中会把导演类忽略,写成SimpleBuilder
抽象建造者
public abstract class AbsBuilder {
/**
* 设置产品的不同部分,以获得不同的产品
*/
public abstract AbsBuilder setPart1();
public abstract AbsBuilder setPart2();
public abstract AbsBuilder setPart3();
/**
* 建造产品
*/
public abstract Product builderProduct();
}
具体建造者
public class SimpleBuilder extends AbsBuilder {
private String part1;
private String part2;
private String part3;
public AbsBuilder setPart1() {
part1 = "功能1";
System.out.println("产品需要功能1");
return this;
}
public AbsBuilder setPart2() {
part2 = "功能2";
System.out.println("产品需要功能2");
return this;
}
public AbsBuilder setPart3() {
part3 = "功能3";
System.out.println("产品需要功能3");
return this;
}
@Override
public Product builderProduct() {
System.out.println("建造者建造产品");
Product product = new Product();
if (part1 != null)
product.addPart(part1);
if (part2 != null)
product.addPart(part2);
if (part3 != null)
product.addPart(part3);
return product;
}
}
场景类
public class SimpleClient {
public static void main(String[] args) {
//创建建造者
AbsBuilder builderA = new SimpleBuilder();
//建造A产品
builderA.setPart1()
.setPart2()
.builderProduct()
.doSomething();
//创建建造者
AbsBuilder builderB = new SimpleBuilder();
//建造B产品
builderB.setPart2()
.setPart3()
.builderProduct()
.doSomething();
}
}