前言
建造者模式又被称呼为生成器模式,这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
建造者模式,是最后能够生产出一个完整的产品,而不是零件,例如KFC的一个套餐,生产一辆完整的汽车,建造一个高楼大厦等。
实现方式
归类后有两种实现方式
<mark>1.通过Client、Director、Builder和Product形成的建造者模式</mark>
这种方式例如建造一个高楼,首先要打地基,然后搭建钢筋水泥结构,设置房屋电线走向,对房屋外貌进行粉刷等等。需要走固定流程
<mark>2.通过静态内部类方式实现零件无序装配话构造</mark>
这种方式使用更加灵活,更符合定义。内部有复杂对象的默认实现,使用时可以根据用户需求自由定义更改内容,并且无需改变具体的构造方式。就可以生产出不同复杂产品。例如KFC的不同组合的套餐。
第一种方式
角色:
抽象建造者(builder):描述具体建造者的公共接口,一般用来定义建造细节的方法,并不涉及具体的对象部件的创建。
具体建造者(ConcreteBuilder):描述具体建造者,并实现抽象建造者公共接口。
指挥者(Director):调用具体建造者来创建复杂对象(产品)的各个部分,并按照一定顺序(流程)来建造复杂对象。
产品(Product):描述一个由一系列部件组成较为复杂的对象。
假设造房简化为如下步骤:(1)地基(2)钢筋工程(3)铺电线(4)粉刷
如果要盖一座房子,首先要找一个建筑公司或工程承包商(指挥者)。承包商指挥工人(具体建造者)过来造房子(产品),最后验收。
<mark>具体步骤:</mark>
1.创建抽象建造者定义造房步骤
2.创建工人具体实现造房步骤
3.创建承包商指挥工人施工
4.验收,检查是否建造完成
话不多说先上代码
抽象建造者:Builder.java
/** * Builder.java * 抽象建造者 */
abstract class Builder {
//地基
abstract void buildA();
//钢筋工程
abstract void buildB();
//铺电线
abstract void buildC();
//粉刷
abstract void buildD();
//完工-获取产品
abstract Product getProduct();
}
具体建造者(工人):ConcreteBuilder.java
/** * ConcreteBuilder.java * 具体建造者(工人) */
public class ConcreteBuilder extends Builder{
private Product product;
public ConcreteBuilder() {
product = new Product();
}
@Override
void buildA() {
product.setBuildA("地基");
}
@Override
void buildB() {
product.setBuildB("钢筋工程");
}
@Override
void buildC() {
product.setBuildC("铺电线");
}
@Override
void buildD() {
product.setBuildD("粉刷");
}
@Override
Product getProduct() {
return product;
}
}
产品(房子):Product.java
/** * Product.java * 产品(房子) */
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 buildA+"\n"+buildB+"\n"+buildC+"\n"+buildD+"\n"+"房子验收完成";
}
}
指挥者:Director.java
/** * Director.java * 指挥者 */
public class Director {
//指挥工人按顺序造房
public Product create(Builder builder) {
builder.buildA();
builder.buildB();
builder.buildC();
builder.buildD();
return builder.getProduct();
}
}
测试类:Test.java
/** * Test.java * 测试类 */
public class Test {
public static void main(String[] args) {
Director director = new Director();
Product create = director.create(new ConcreteBuilder());
System.out.println(create.toString());
}
}
运行结果:
第二种方式
<mark>主要有三种角色</mark>
抽象建造者、具体建造者、产品
比第一种方式少了指挥者,主要是因为第二种方式把指挥者交给服务员来操作,使得产品的创建更加简单灵活。
例如麦当劳的套餐,服务员(具体建造者)可以随意搭配任意几种产品(零件)组成一款套餐(产品),然后出售给客户。
具体步骤:
1.建造抽象建造者定义麦当劳的产品(类别)
2.创建具体的建造者
3.创建套餐产品
3.创建服务员将各部件组合成套餐
代码:
抽象建造者:Builder.java
/** * Builder.java * 建造者 */
abstract class Builder {
//汉堡
abstract Builder bulidA(String mes);
//饮料
abstract Builder bulidB(String mes);
//薯条
abstract Builder bulidC(String mes);
//甜品
abstract Builder bulidD(String mes);
//获取套餐
abstract Product build();
}
产品:Product.java
/** * Product.java * 产品(麦当劳套餐) */
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 buildA+"\n"+buildB+"\n"+buildC+"\n"+buildD+"\n"+"组成套餐";
}
}
具体建造者:ConcreteBuilder.java
/** * ConcreteBuilder.java * 具体建造者(服务员) */
public class ConcreteBuilder extends Builder{
private Product product;
public ConcreteBuilder() {
product = new Product();
}
@Override
Product build() {
return product;
}
@Override
Builder bulidA(String mes) {
product.setBuildA(mes);
return this;
}
@Override
Builder bulidB(String mes) {
product.setBuildB(mes);
return this;
}
@Override
Builder bulidC(String mes) {
product.setBuildC(mes);
return this;
}
@Override
Builder bulidD(String mes) {
product.setBuildD(mes);
return this;
}
}
测试类:Test.java
/** * Test.java * 测试类 */
public class Test {
public static void main(String[] args) {
ConcreteBuilder concreteBuilder = new ConcreteBuilder();
Product build = concreteBuilder
.bulidA("牛肉煲")
// .bulidC("全家桶")
.bulidD("冰淇淋")
.build();
System.out.println(build.toString());
}
}
运行
第二种建造方式比较灵活,它没有规定套餐是什么样的,而是规定了套餐是由几个部分组成(分类),然后具体建造的单类产品是什么掌握着顾客的手中,也就是说顾客知道套餐是由汉堡、饮料、薯条、甜品四种组成,然后可以随意进行搭配。比如汉堡有牛肉煲、鸡肉堡,饮料有可乐、果汁,薯条有大份、中份、小份(这里把薯条换成小吃比较好),甜品有冰淇淋、蛋糕等。
猜想
我们知道抽象工厂是专门生产各种具体商品类的,可以做一系类商品,我们把这个揉和进来,就相当于麦当劳的菜单了,菜单上也是按照产品系列分类的,然后我们也可以创建专门生产各种套餐的工厂,那么顾客更加简便了,不需要自己挨个点,只需要点套餐A、B、C即可。