首先呢看下建造者的定义是什么样的,先读一遍
建造者模式(Builder Pattern)是一种创建型设计模式,它主要用于将一个复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表现形式。这种模式通过一系列可重用的独立的类(称为建造者或构建器)来一步一步创建一个复杂的对象,而不需要知道具体的内部构造细节
建造者模式的主要优点:
建造者模式的主要缺点:
网图来一张
好了,直接上代码,这里我们先构建一个CarProduct,很多描述都写在了对应的注释中了啊,这里就不过多赘述
package com.mtgg.laoxiang.service.example.designer.builder;
import lombok.Data;
/**
* 要构建的产品对象
*/
@Data
public class CarProduct {
private String partA;
private String partB;
private String partC;
}
package com.mtgg.laoxiang.service.example.designer.builder;
/**
* 建造者抽象类
*/
public abstract class Builder {
//建造产品时,实例化,相当于统一放到一个地方,product相当于一个封装,里面可以放各种东西的组成
protected CarProduct carProduct = new CarProduct();
//建造,建造各种东西然后set到product中
public abstract void builderPartA();
public abstract void builderPartB();
public abstract void builderPartC();
//提供获得产品的入口,要获得这个产品,就调用这个方法
public CarProduct getResult() {
return carProduct;
}
}
上面定义了产品,构造器,获取产品的方法,下面这个就是构造器要具体干的活了
package com.mtgg.laoxiang.service.example.designer.builder;
public class BJBuilder extends Builder{
@Override
public void builderPartA() {
System.out.println("构建个1球");
carProduct.setPartA("1球");
}
@Override
public void builderPartB() {
System.out.println("构建个2球");
carProduct.setPartB("2球");
}
@Override
public void builderPartC() {
System.out.println("构建个3球");
carProduct.setPartC("3球");
}
}
package com.mtgg.laoxiang.service.example.designer.builder;
public class HZBuilder extends Builder{
@Override
public void builderPartA() {
System.out.println("构建个1香蕉");
carProduct.setPartA("1香蕉");
}
@Override
public void builderPartB() {
System.out.println("构建个2香蕉");
carProduct.setPartB("2香蕉");
}
@Override
public void builderPartC() {
System.out.println("构建个3香蕉");
carProduct.setPartC("3香蕉");
}
}
指挥者来了,指挥我到底想要啥,什么数量,什么顺序,定义几个图纸来交给构造器去构造,然后main使用的时候直接调用这个定义好的流程,就能拿到对应的产品
package com.mtgg.laoxiang.service.example.designer.builder;
/**
* 指挥者
* 控制生成流程
*/
public class Director {
//这个抽象类可以定义成全局变量,也可以定义接口,此处可以引用接口,更不违反原则
private Builder builder;
/**
* 注入builder
*/
private Director(Builder builder) {
this.builder = builder;
}
/**
* 控制流程,此处类似使用模板模式
*/
public CarProduct construct2(){
builder.builderPartC();
builder.builderPartA();
return builder.getResult();
}
public CarProduct construct(){
builder.builderPartB();
builder.builderPartA();
builder.builderPartC();
return builder.getResult();
}
public static void main(String[] args) {
//此处可选择不同的建造者建造产品
Director director = new Director(new HZBuilder());
CarProduct construct = director.construct();
System.out.println(construct);
director = new Director(new BJBuilder());
CarProduct construct1 = director.construct2();
System.out.println(construct1);
}
}
*构建个2香蕉
构建个1香蕉
构建个3香蕉
Product(partA=1香蕉, partB=2香蕉, partC=3香蕉)
构建个3球
构建个1球
Product(partA=1球, partB=null, partC=3球) *
如果我想建造另外一个对象呢?难道类似的类都要加一份?那肯定是low的,做法如下,
可以加具体建造,定义好要建造的东西,再建一个指挥者方法,尽量不要在原来的方法上改,改造后如下
假如有另一个对象PhoneProduct
@Data
public class PhoneProduct {
private String pa;
private String pb;
private String pc;
}
Builder中加上要构建的这个产品,并加个返回产品的方法,所以这么看的话那几个构建的抽象方法就不能太个性化,最好抽象一些,像是定义三四个工厂一样,具体怎么生产看子类实现
public abstract class Builder {
//建造产品时,实例化,相当于统一放到一个地方,product相当于一个封装,里面可以放各种东西的组成
//另外一个产品
protected PhoneProduct phoneProduct = new PhoneProduct();
……………………
public PhoneProduct getPhoneResult() {
return phoneProduct;
}
}
好了我们定义一个子类去构建具体的内容,不用改另外一个对象的构建,保证对扩展开放,对修改关闭
public class XMBuilder extends Builder{
@Override
public void builderPartA() {
System.out.println("小米a");
phoneProduct.setPa("pa");
}
@Override
public void builderPartB() {
System.out.println("小米b");
phoneProduct.setPb("pb");
}
@Override
public void builderPartC() {
System.out.println("小米c");
phoneProduct.setPc("pc");
}
}
指挥者我们改造一下,构建顺序以及数量都可以抽出来共用,只需要定义construct2或constructPhone方法,指定模板,返回产品就OK了,想要啥产品要啥产品
public class Director {
//这个抽象类可以定义成全局变量,也可以定义接口,此处可以引用接口,更不违反原则
private Builder builder;
/**
* 注入builder
*/
private Director(Builder builder) {
this.builder = builder;
}
/**
* 构建模板 定义构建顺序以及内容
*/
public void buildTemplateA(){
builder.builderPartB();
builder.builderPartA();
builder.builderPartC();
}
/**
* 构建模板 定义构建顺序以及内容
*/
public void buildTemplateB(){
builder.builderPartC();
builder.builderPartA();
}
/**
* 构建以及获取car产品的入口
*/
public CarProduct construct2(){
this.buildTemplateB();
return builder.getResult();
}
//不同形态的car产品
public CarProduct construct(){
this.buildTemplateA();
return builder.getResult();
}
//这个是构建和获取phone产品的入口
public PhoneProduct constructPhone(){
this.buildTemplateA();
return builder.getPhoneResult();
}
public static void main(String[] args) {
//此处可选择不同的建造者建造产品
Director director = new Director(new HZBuilder());
CarProduct construct = director.construct();
System.out.println(construct);
director = new Director(new BJBuilder());
CarProduct construct1 = director.construct2();
System.out.println(construct1);
//构建另外一个产品,使用时指定用XMBuilder这个厂家生产的就行
director = new Director(new XMBuilder());
PhoneProduct construct2 = director.constructPhone();
System.out.println(construct2);
}
}
下面这是执行结果
构建个2香蕉
构建个1香蕉
构建个3香蕉
CarProduct(partA=1香蕉, partB=2香蕉, partC=3香蕉)
构建个3球
构建个1球
CarProduct(partA=1球, partB=null, partC=3球)
小米b
小米a
小米c
PhoneProduct(pa=pa, pb=pb, pc=pc)
并行构建我还没事件完毕,对不起大家,后面我补上,主要思路就是用CyclicBarrier,大家可以先试一下