1.网上大概有三个观点标明此模式意图:
(1)直接摆出类图,类似于菜鸟编程那种,肯德基,汉堡,薯条等等,说实在的可以抄,但是抄完之后并没卵用,真正的工作中能和快餐有相同的使用场景么?
(2)还有就是构造方法或者set方法太多导致需要返回本身对象进行链式调用,好处就是需要最后需要强制调用build()方法进行对象创建,规避了直接调用set()方法导致步骤缺失,但这好像也不是建造者模式的初心。
class Product {
private Object partA;
private Object partB;
private Object partC;
public Object getPartA() {
return partA;
}
public void setPartA(Object partA) {
this.partA = partA;
}
public Object getPartB() {
return partB;
}
public void setPartB(Object partB) {
this.partB = partB;
}
public Object getPartC() {
return partC;
}
public void setPartC(Object partC) {
this.partC = partC;
}
@Override
public String toString() {
return "Product{" +
"partA=" + partA +
", partB=" + partB +
", partC=" + partC +
'}';
}
}
abstract class AbstractBuilder {
abstract Product buildPartA(Product product);
abstract Product buildPartB(Product product);
abstract Product buildPartC(Product product);
}
class Build1 extends AbstractBuilder {
@Override
Product buildPartA(Product product) {
product.setPartA("调用联动优势查询公司账户余额,1000元");
return product;
}
@Override
Product buildPartB(Product product) {
product.setPartB("调用联动优势查询公司账户日消费总金额,100元");
return product;
}
@Override
Product buildPartC(Product product) {
product.setPartC("调用联动优势查询公司账户月消费总金额,5000元");
return product;
}
}
class Build2 extends AbstractBuilder {
@Override
Product buildPartA(Product product) {
product.setPartA("调用易宝支付查询公司账户余额,600元");
return product;
}
@Override
Product buildPartB(Product product) {
product.setPartB("调用易宝支付查询公司账户日消费总金额,900元");
return product;
}
@Override
Product buildPartC(Product product) {
product.setPartC("调用易宝支付查询公司账户月消费总金额,57000元");
return product;
}
}
public class Director {
private AbstractBuilder abstractBuilder;
public Director(AbstractBuilder abstractBuilder) {
this.abstractBuilder = abstractBuilder;
}
public Product build(){
Product product = new Product();
product = abstractBuilder.buildPartA(product);
product = abstractBuilder.buildPartB(product);
product= abstractBuilder.buildPartC(product);
return product;
}
public static void main(String[] args) {
//这里使用简单工厂更好,方便起见直接死代码
AbstractBuilder builder = new Build2();
Director director = new Director(builder);
Product buildProduct = director.build();
System.out.println(buildProduct);
}
}
当使用Build1时,打印Product{partA=调用联动优势查询公司账户余额,1000元, partB=调用联动优势查询公司账户日消费总金额,100元, partC=调用联动优势查询公司账户月消费总金额,5000元}
当使用Build2时,打印Product{partA=调用易宝支付查询公司账户余额,600元, partB=调用易宝支付查询公司账户日消费总金额,900元, partC=调用易宝支付查询公司账户月消费总金额,57000元}
这个例子的场景是,公司对接了很多支付方式,但是财务人员每次查询余额或者消费情况只能一个一个登录具体的三方后台去查询,很不方便,希望提供一个聚合页面,集中展示。
下面我就着自己的理解解释下建造者模式
老规矩:提到设计模式,我觉着首先要搞清楚一点,在对某个功能进行开发或者设计模式重构时,要分清哪些是可变的,哪些是不可变(共性)的。
在不可变的就是页面展示 公司账户余额,日消费金额,月消费金额
经常变动的是查询这三个条件对应的三方公司接口,地址,加密方式等等。
所以我们将可变的放入具体的builder中。然后由Director 规定指定的步骤聚合查询动作(这是不可变的),由具体子类去调用查询接口,以达到开闭原则。核心就是AbstractBuilder 与 子类形成多态,指向子类的实现。
这样新增或者修改某个三方支付接口,能确保不动其它的支付方式,降低测试回归维度。