建造者模式
- 建造者模式属于创建型模式,它提供了一种创建对象的最佳方式。
- 定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
- 主要作用:在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象。
- 用户只需要给出指定复杂对象的类型和内容,建造者模式负责按顺序创建复杂对象(把内部的建造过程和细节隐藏起来)
- 例子:工厂(建造者模式)︰负责制造汽车(组装过>程和细节在工厂内)
// 有指挥的建造
public abstract class Builder {
abstract void builderA(); //步骤1
abstract void builderB();//步骤2
abstract void builderC();//步骤3
abstract void builderD();//步骤4
// 完工:得到产品
abstract Product getProduct();
}
//产品
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() {
this.product = new Product();
}
@Override
void builderA() {
product.setBuilderA("步骤1");
System.out.println("步骤1");
}
@Override
void builderB() {
product.setBuilderB("步骤2");
System.out.println("步骤2");
}
@Override
void builderC() {
product.setBuilderC("步骤3");
System.out.println("步骤3");
}
@Override
void builderD() {
product.setBuilderD("步骤4");
System.out.println("步骤4");
}
@Override
Product getProduct() {
return product;
}
}
//指挥:核心,负责指挥构建一个工程,工程如何构建,由它次定
public class Director {
//指挥工人按顺序建房子
public Product build(Builder builder){
builder.builderA();
builder.builderB();
builder.builderC();
builder.builderD();
return builder.getProduct();
}
}
public class Test {
public static void main(String[] args) {
Director director = new Director();
Product build = director.build(new Worker());
System.out.println(build.toString());
}
}
// 用户自己决定建造细节
public abstract class DinnerBuilder {
abstract DinnerBuilder builderA(String msg); //步骤1
abstract DinnerBuilder builderB(String msg);//步骤2
abstract DinnerBuilder builderC(String msg);//步骤3
abstract DinnerBuilder builderD(String msg);//步骤4
// 完工:得到产品
abstract Product getProduct();
}
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 Waiter extends DinnerBuilder {
private Product product;
public Waiter() {
this.product = new Product();
}
@Override
DinnerBuilder builderA(String msg) {
product.setBuilderA(msg);
return this;
}
@Override
DinnerBuilder builderB(String msg) {
product.setBuilderB(msg);
return this;
}
@Override
DinnerBuilder builderC(String msg) {
product.setBuilderC(msg);
return this;
}
@Override
DinnerBuilder builderD(String msg) {
product.setBuilderD(msg);
return this;
}
@Override
Product getProduct() {
return product;
}
}
public class Person {
public static void main(String[] args) {
Waiter waiter = new Waiter();
waiter.builderA("猪肉炖粉条");
Product product = waiter.getProduct();
System.out.println(product);
}
}
-
上面示例是Builder模式的常规用法,导演类Director在Builder模式中具有很重要的作用,它用于指导具体构建者如何构建产品,控制调用先后次序,并向调用者返回完整的产品类,但是有些情况下需要简化系统结构,可以把Director和抽象建造者进行结合。
-
通过静态内部类方式实现零件无序装配构造,这种方式使用更加灵活,更符合定义。内部有复杂对象的默认实现,使用时可以根据用户需求自由定义更改内容,并且无需改变具体的构造方式。就可以生产出不同复杂产品。
-
比如:比如麦当劳的套餐,服务员(具体建造者)可以随意搭配任意几种产品(零件)组成一款套餐(产品),然后出售给客户。比第一种方式少了指挥者,主要是因为第二种方式把指挥者交给用户来操作,使得产品的创建更加简单灵活。
-
优点:
- 产品的建造和表示分离,实现了解耦。使用建造者模式可以使客户端不必知道产品内部组成的细节。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰
- 具体的建造者类之间是相互独立的,这有利于系统的扩展。增加新的具体建造者无需修改原有类库的代码,符合“开闭原则“。
-
缺点:
- 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似;如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
- 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。