应用场景
- 相同的方法,不同的执行顺序,产生不同的事件结果时;
- 多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时
- 产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能,这个时候使用建造者模式非常合适;
- 当初始化一个对象特别复杂,如参数多,且很多参数都具有默认值时。
意图
- 将复杂的对象的构建过程与它的表示分离,这样就可以灵活控制对象的构建过程,使得同样的构建过程,因为具体的生成器不同,创建不同的表示。
参与者
生产者:Builder
职责
- 本身是一个抽象类
- 它对产品的各个组成部分,指定抽象的行为接口
- 返回一个空的产品对象,具体什么产品对象在ConcreteBuilder实现
具体生产者:ConcreteBuilder
职责
- 本身是一个实现Builder的实体类
- 提供获取一个具体的产品对象的方法
引导者:Director
职责
- 本身是一个类,类中具有Builder的引用
- 它提供一个方法,参数Builder,通过操作Builder接口,用Builder按照其指定的顺序去完成Produt的构造。
产品:Product
职责
- 本身是包含定义组成,部件的类,也就是最终组装的产品。
结构
协作
- 客户创建一个引导器Diretior,引用Builder接口进行配置
- 生成器处理引导器的请求,按照规定的次序,将部件组装到产品中。
- 客户引用生成器对象,获取组装配置后的产品
交互图
实例
场景:一个公司开发产品,参与者:客户,产品经理,技术主管,程序员。
需求:客户给产品经理需求,产品经理分析需求,告诉技术主管,或者程序员开发产品给客户。
(1)产品类
/**
* 产品类
* Created by shixinshan on 2018/10/25.
*/
public class Product {
private String appName;
private String appFuction;
private String appSystem;
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getAppFuction() {
return appFuction;
}
public void setAppFuction(String appFuction) {
this.appFuction = appFuction;
}
public String getAppSystem() {
return appSystem;
}
public void setAppSystem(String appSystem) {
this.appSystem = appSystem;
}
@Override
public String toString() {
return "Product [appName=" + appName + ", appFuction=" + appFuction
+ ", appSystem=" + appSystem + "]";
}
}
(2)抽象建造者类——技术主管(可省略)
/**
* 抽象建造者类——技术主管
* Created by shixinshan on 2018/10/25.
*/
public abstract class Builder {
public abstract Builder setAppName(String appName);
public abstract Builder setAppFuction(String appFuction);
public abstract Builder setAppSystem(String appSystem);
public Product build(){
return null;
}
}
(3)具体建造者类——程序员
/**
* 具体建造者类——程序员
* Created by shixinshan on 2018/10/25.
*/
public class WorkBuilder extends Builder {
private Product product;// 产品类
private InnerProduct innerProduct = new InnerProduct();// 产品缓冲类
@Override
public Builder setAppName (String appName){
innerProduct.setAppName(appName);
return this;
}
@Override
public Builder setAppFuction (String appFuction){
innerProduct.setAppFuction(appFuction);
return this;
}
@Override
public Builder setAppSystem (String appSystem){
innerProduct.setAppSystem(appSystem);
return this;
}
@Override
public Product build () {
product = new Product();
product.setAppName(innerProduct.getAppName());
product.setAppFuction(innerProduct.getAppFuction());
product.setAppSystem(innerProduct.getAppSystem());
return product;
}
/**
* 产品缓冲类
*/
private class InnerProduct {
private String appName;
private String appFuction;
private String appSystem;
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getAppFuction() {
return appFuction;
}
public void setAppFuction(String appFuction) {
this.appFuction = appFuction;
}
public String getAppSystem() {
return appSystem;
}
public void setAppSystem(String appSystem) {
this.appSystem = appSystem;
}
}
}
(4)指挥者类——产品经理(可省略)
/**
* 指挥者类——产品经理
* Created by shixinshan on 2018/10/25.
*/
public class Director {
public Product create(Builder builder,String system,String appName,String appFunction) {
Product product = builder.setAppSystem(system)
.setAppName(appName)
.setAppFuction(appFunction)
.build();
return product;
}
}
(4)客户
/**
* 客户
* Created by shixinshan on 2018/10/25.
*/
public class Client {
public Product getProduct(String system,String appName,String appFuntion){
Director director = new Director();//产品经理
WorkBuilder workBuilder = new WorkBuilder();
director.create(workBuilder,system,appName,appFuntion);
Product build = workBuilder.build();
return build;
}
}
测试
@Test
public void builder() throws Exception {
Client client = new Client();
Product product = client.getProduct("android", "QQ", "chat");
System.out.println("product = "+product.toString());
}
结果:
product = Product [appName=QQ, appFuction=chat, appSystem=android]
Process finished with exit code 0
Builder模式变种(常用)
public class Person {
private String name;
private int age;
private double height;
private double weight;
private Person(Builder builder){
this.name=builder.name;
this.age=builder.age;
this.height=builder.height;
this.weight=builder.weight;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
static class Builder{
private String name;
private int age;
private double height;
private double weight;
public Builder setName(String name) {
this.name=name;
return this;
}
public Builder setAge(int age) {
this.age=age;
return this;
}
public Builder setHeight(double height) {
this.height=height;
return this;
}
public Builder setWeight(double weight) {
this.weight=weight;
return this;
}
public Person build(){
return new Person(this);// build()返回Person对象
}
}
}