23种设计模式——建造者模式
定义
- 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
主要作用
- 在用户不知道对象的建造过程和细节的情况下就就可以直接创建复杂的对象
package com.mjh.builder;
//抽象的建造者 方法
public abstract class Build {
abstract void buildA();//地基
abstract void buildB();//钢筋工程
abstract void buildC();//铺电线
abstract void buildD();//粉刷
//完工 得到产品
abstract Product getProduct();
}
package com.mjh.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 + '\'' +
'}';
}
}
package com.mjh.builder;
//具体的建造者 工人
public class Worker extends Build{
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;
}
}
package com.mjh.builder;
public class Test {
public static void main(String[] args) {
//指挥
Director director = new Director();
//指挥具体的工人完成产品
Product build = director.build(new Worker());
System.out.println(build.toString());
}
}
- 上面实例是Builder模式的常规用法,Director在builder模式中具有很重要的作用,它用于指导具体构建者如何构建产品,控制调用先后顺序,并向调用者返回完整的产品类,但是有些情况下需要简化系统结构,可以把Director和和抽象建造者进行组合。
- 通过静态内部类方式实现零件无序装配构造,这种方法更加灵活,更加符合定义。内部有复杂对象的默认实现,使用时可以根据用户需求自由定义更改内容,并且无需更改具体的构造方式,就可以产生出不同的复杂产品
package com.mjh.builder.demo02;
public abstract class Builder {
abstract void buildA(String msg);//汉堡
abstract void buildB(String msg);//薯条
abstract void buildC(String msg);//可乐
abstract void buildD(String msg);//甜品
abstract Product getProduct();
}
package com.mjh.builder.demo02;
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) {
BuildA = buildA;
}
public String getBuildB() {
return BuildB;
}
public void setBuildB(String buildB) {
BuildB = buildB;
}
public String getBuildC() {
return BuildC;
}
public void setBuildC(String buildC) {
BuildC = buildC;
}
public String getBuildD() {
return BuildD;
}
public void setBuildD(String buildD) {
BuildD = buildD;
}
@Override
public String toString() {
return "Product{" +
"BuildA='" + BuildA + '\'' +
", BuildB='" + BuildB + '\'' +
", BuildC='" + BuildC + '\'' +
", BuildD='" + BuildD + '\'' +
'}';
}
}
package com.mjh.builder.demo02;
public class Worker extends Builder{
private Product product;
public Worker() {
product=new Product();
}
@Override
Builder buildA(String msg) {
product.setBuildA(msg);
return this;
}
@Override
Builder buildB(String msg) {
product.setBuildB(msg);
return this;
}
@Override
Builder buildC(String msg) {
product.setBuildC(msg);
return this;
}
@Override
Builder buildD(String msg) {
product.setBuildD(msg);
return this;
}
@Override
Product getProduct() {
return product;
}
}
package com.mjh.builder.demo02;
public class Test {
public static void main(String[] args) {
Worker worker = new Worker();
//链式编程:在原来的基础上,可以自由组合了,如果不组合,也有默认的套餐
Product product = worker.buildA("鸡翅").buildB("全家桶")
.getProduct();
System.out.println(product.toString());
}
}
优点
- 产品的构建和表示分离,实现了解耦。使用建造者模式可以是客户端不必知道产品的内部细节
- 将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰
- 具体的构建者之间是相互独立的,有利于系统的扩展,增加新的具体的构建者无需更改原有类库的代码,符合“开闭原则”;
缺点
- 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品间的差异性很大,则不符合使用建造者模式,因此其使用范围受到一定的限制
- 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大