目的:将产品与产品的创建过程解耦 。他是按照相应的步骤来构建产品
下面看一下UML序列图
对于序列图的一个解释
Product.java
package com.pxx;
public class Product {
private String shape;
private int height;
private String color;
public Product(String shape, int height, String color) {
this.shape = shape;
this.height = height;
this.color = color;
}
public String getShape() {
return shape;
}
public void setShape(String shape) {
this.shape = shape;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
public String toString() {
return "com.pxx.Product{" +
"shape='" + shape + '\'' +
", height=" + height +
", color='" + color + '\'' +
'}';
}
}
建造者的抽象类或者接口
ProductBuilder.java
package com.pxx;
public interface ProductBuilder {
//定义好产品相关的各种操作
void buildShape();
void buildHeight();
void buildColor();
Product buildProduct();
}
下面是具体的构建者对象
AoliaoConcreteBuilder.java
package com.pxx;
public class AoliaoConcreteBuilder implements ProductBuilder {
//这里面必须聚合一个产品类
Product product;
//这里面传的是一个具体的构建者对象,带着参数进来,然后赋值给一个产品
//传进来之后再来构建相关参数
public AoliaoConcreteBuilder(String shape,int height,String color) {
//这里就已经赋值了
this.product = new Product(shape,height,color);
}
@Override
public void buildShape() {
System.out.println("奥利奥形状:" +product.getShape());
}
@Override
public void buildHeight() {
System.out.println("奥利奥高度:" + product.getHeight() + "厘米");
}
@Override
public void buildColor() {
System.out.println("奥利奥颜色:" + product.getColor());
}
//返回这个对象
public Product buildProduct() {
return product;
}
}
Director.java
package com.pxx;
public class Director {
//这里面我们需要调用ProductBuilder里面所有方法(这个是所有建造者的父类,也就是说,只要实现它的建造者都能传进来)
//并且最后给我们返回一个对象
//注意这个对象不是直接给我们运行
//相当于是一个分发的结果
private ProductBuilder productBuilder;//这里可以直接传入比如Aoliao这个对象,因为是实现ProductBuilder
public Director(ProductBuilder productBuilder) {
this.productBuilder = productBuilder;
}
public Product constructProduct() {
productBuilder.buildShape();
productBuilder.buildHeight();
productBuilder.buildColor();
return productBuilder.buildProduct();
}
}
看一下客户端Client.java
package com.pxx;
public class Client {
public static void main(String[] args) {
//有一个奥利奥的具体构建者对象
AoliaoConcreteBuilder aoliao = new AoliaoConcreteBuilder("圆形",2,"蓝色");
//利用Director来调用具体的构建者
Director director = new Director(aoliao);//要调用这个对象的方法
Product p = director.constructProduct();//这里就开始构建
System.out.println(p);
}
}
运行结果
上面代码还是要进行一个重构,这里我们这里是可以采用链式编程
我们需要反复拿这个建造者对象一直调用吗? 不需要,调用一下,然后返回当前调用者对象就可以了。
代码重构
ProductBuilder.java
package com.pxx;
public interface ProductBuilder {
//定义好产品相关的各种操作
AoliaoConcreteBuilder buildShape();
AoliaoConcreteBuilder buildHeight();
AoliaoConcreteBuilder buildColor();
Product buildProduct();
}
AoliaoConcreteBuilder.java
package com.pxx;
public class AoliaoConcreteBuilder implements ProductBuilder {
//这里面必须聚合一个产品类
Product product;
//这里面传的是一个具体的构建者对象,带着参数进来,然后赋值给一个产品
//传进来之后再来构建相关参数
public AoliaoConcreteBuilder(String shape,int height,String color) {
//这里就已经赋值了
this.product = new Product(shape,height,color);
}
@Override
public AoliaoConcreteBuilder buildShape() {
System.out.println("奥利奥形状:" +product.getShape());
return this;
}
@Override
public AoliaoConcreteBuilder buildHeight() {
System.out.println("奥利奥高度:" + product.getHeight() + "厘米");
return this;
}
@Override
public AoliaoConcreteBuilder buildColor() {
System.out.println("奥利奥颜色:" + product.getColor());
return this;
}
//返回这个对象
public Product buildProduct() {
return product;
}
}
Director.java
运行结果
其实,说一下,有时候这个建造者模式组件表现的不会那么齐全,比如我们稍微去看一下StringBuilder的源码
看到这个StringBuilder后面有个Builder就应该猜出来,它是一个建造者或者建造者的抽象层
我们可以看到StringBuilder继承了一个AbstractStringBuilder类,这个就像是具体的建造者对象去实现了建造者抽象
再去看一下AbstractStringBuilder类
那么一看这个类就是一个抽象类,这是不是就让我们想起建造者抽象,但是它还不是,我们继续往下追。
这里面就有我们常用的append抽象方法
这个就可以理解为建造者抽象,产品的话可以考虑为没有。
而且这个里面方法都是链式编程
这个this就是一个StringBuilder的一个具体的对象。
好了,这个建造者模式先说到这。