-
建造者模式也属于创建型模式,它提供了一种创建对象的最佳方式。
-
定义:将一个复杂的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
-
主要作用:在用户不知道 对象的建造过程和细节 的情况下就可以直接创建复杂的对象。
-
用户只需要给出指定复杂对象的类型和内容,建造者模式复杂按顺序
创建复杂对象(把内部的建造过程和细节隐藏起来)
案例:
假设造房简化为如下步骤:
1.地基
2.钢筋工程
3.铺电线
4.粉刷
如果要盖一座房子,首先找一个建筑公司或工程承包商(指挥者),承包商指挥工人(具体建造者),过来造房子(产品),最后验收
UML类图
首先写一个抽象Builder类,Builder里面有四个工程
//产品:房子
public class Product {
private String buildA;
private String buildB;
private String buildC;
private String buildD;
public String getBuildA() {
return buildA;
}
public void setBuildA(String buildA) {
this.buildA = buildA;
}
public String getBuildB() {
return buildB;
}
public void setBuildB(String buildB) {
this.buildB = buildB;
}
public String getBuildC() {
return buildC;
}
public void setBuildC(String buildC) {
this.buildC = buildC;
}
public String getBuildD() {
return buildD;
}
public void setBuildD(String buildD) {
this.buildD = buildD;
}
@Override
public String toString() {
return "Product{" +
"buildA='" + buildA + '\'' +
", buildB='" + buildB + '\'' +
", buildC='" + buildC + '\'' +
", buildD='" + buildD + '\'' +
'}';
}
}
在写一个工人类
//真正的建造者,工人
public class Worker extends Builder {
private Product product;
public Worker(){
product=new Product();
}
@Override
void buildA() {
product.setBuildA("地基");
System.out.println("地基");
}
@Override
void buildB() {
product.setBuildB("钢筋工程");
System.out.println("钢筋工程");
}
@Override
void buildC() {
product.setBuildC("铺电线");
System.out.println("铺电线");
}
@Override
void buildD() {
product.setBuildD("粉刷");
System.out.println("粉刷");
}
@Override
Product getproduct() {
return product;
}
}
最后是指挥者,指挥工人建房子
//指挥:核心,负责指挥构建一个工程,工程如何创建,由它决定
public class Director {
public Product builder(Builder builder){
builder.buildA();
builder.buildB();
builder.buildC();
builder.buildD();
return builder.getproduct();
}
}
最后在测试一下Test
public class Test {
public static void main(String[] args) {
Director director=new Director();
Product builder = director.builder(new Worker());
System.out.println(builder.toString());
}
}
上面的示例是Builder模式的常规用法,导演类Director在Builder模式中具有很重要的作用,它用于指导具体构建者如何构建产品,控制调用先后次序,并向调用者返回完整的产品类,但有些情况下需要简化系统结构,可以把Director和抽象建造者进行结合。
例如一个肯德基店,店中有套餐,但是客户也可以自己点餐。这时我们就可以把指挥者和建造者结合起来。看代码实例
还是一个抽象的Builder类,其中有汉堡,可乐,薯条,甜点
public abstract class Builder {
abstract Builder builderA(String msg);//汉堡
abstract Builder builderB(String msg);//可乐
abstract Builder builderC(String msg);//薯条
abstract Builder builderD(String msg);//甜品
abstract Product product();
}
我们需要在创建一个产品类 Product
public class Product {
private String builderA="汉堡";
private String builderB="可乐";
private String builderC="薯条";
private String builderD="甜品";
public String getBuilderA() {
return builderA;
}
public void setBuilderA(String builderA) {
this.builderA = builderA;
}
public String getBuilderB() {
return builderB;
}
public void setBuilderB(String builderB) {
this.builderB = builderB;
}
public String getBuilderC() {
return builderC;
}
public void setBuilderC(String builderC) {
this.builderC = builderC;
}
public String getBuilderD() {
return builderD;
}
public void setBuilderD(String builderD) {
this.builderD = builderD;
}
@Override
public String toString() {
return "Product{" +
"builderA='" + builderA + '\'' +
", builderB='" + builderB + '\'' +
", builderC='" + builderC + '\'' +
", builderD='" + builderD + '\'' +
'}';
}
}
这时我们就需要一个服务员,或者自己点餐,我们把指挥者和建造者结合在了一起
public class Worker extends Builder {
private Product product;
public Worker() {
product=new Product();
}
@Override
Builder builderA(String msg) {
product.setBuilderA(msg);
return this;
}
@Override
Builder builderB(String msg) {
product.setBuilderB(msg);
return this;
}
@Override
Builder builderC(String msg) {
product.setBuilderC(msg);
return this;
}
@Override
Builder builderD(String msg) {
product.setBuilderD(msg);
return this;
}
@Override
Product product() {
return product;
}
}
最后测试一下Test
public class Test {
public static void main(String[] args) {
Worker worker=new Worker();
//链式编程 在原来的基础上,可以自由组合了,如果不组合也有默认的套餐
Product product = worker.builderA("全家桶").builderB("雪碧")
.product();
System.out.println(product.toString());
}
}
建造者优点和缺点:
应用场景和抽象工厂的区别