读《设计模式:可复用面向对象软件的基础》--创建型模式之建造者模式(Builder)

建造者模式(Builder)

意图

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

动机

建造者返回给客户一个完整的的产品对象,而客户端无须关心该对象所包含的属性和组建方式。
如果想要通俗易懂可以参考《大话设计模式》第13章建造模式部分,里面通过做饭来引出建造者模式,用户去吃饭,无需知道师傅放的什么食材以及如何烹饪。再者,还拿汽车来说,我们去买汽车无需知道汽车具体的零件和如何组装的。
假如我们要生产一辆车,假如我们只考虑车有四个轮子,一个发动机,一个车架,常规方法我们需要再需要车的地方,生产四个轮子,一个车架,一个发动机,当我们对车的轮子或者发动机有新的需求,我们又要重改代码,假如我们再另一个地方又需要创建一台车,那么又需要把代码重写一遍,构建过程无法被复用,代码凌乱, 容易错写或者少写,假如少生产一个轮子,那么这个对象就没有使用价值了。
建造者模式就适合解决这一类问题:构建一个对象的过程是相同的,只不过是细节是不同的。也就实现了建造者模式的初衷:构建和表示分离,使得同样的构建过程可以创建不同的表示。

使用场景

(1) 需要生成的产品对象有复杂的内部结构。
(2) 需要生成的产品对象的属性相互依赖,需要指定其生成顺序。
(3) 对象的创建过程独立于创建该对象的类。在建造者模式中通过引入了指挥者类,将创建过程封装在指挥者类中,而不在建造者类和客户类中。
(4) 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。

结构

建造者模式

角色

Builder

为创建一个Product对象的各个部件指定抽象接口。

ConcreteBuilder

1.实现Builder以构造和装配该产品的各个部件。
2.定义并明确它所创建的表示。
3.提供一个检索产品的接口。

Director

指导构造一个使用Builder接口的对象

Product

被构造的复杂对象。

协作

协作

效果

  1. 可以改变一个产品的内部表示。
  2. 将构造和表示分离。
  3. 对构建的过程进行更加精细的控制。

相关模式

  1. Abstract Factory(3.1)与Builder相似,因为它也可以创建复杂对象。主要的区别是Builder模式着重于一步步构造一个复杂对象(主要是体现构造同一个产品的过程),Abstract Factory着重于多个系列的产品对象(简单的或是复杂的产品族中的不同产品)。Builder在最后的一步返回产品,而对于Abstract Factory来说,产品是立即返回的。
  2. Composite(4.3)通常是用Builder生成的。

具体场景代码描述

/**
* 场景:简单一点的例子,我们制造一辆自行车,主要构成包括:前轮子,后轮子,车架,链子
* 第一步:创建一个Builder抽象类,来将制造过程给稳定(非制造顺序,而是包括哪些步骤),这样就可以避免我们在常规制造中漏步骤的问题(比如少了链子)
* 第二步:创建一个具体的建造者去继承这个方法,去建造一个具体的对象,具体的构造方式写在此类中。
* 第三步:创建一个Director,去指导制造过程(可以在此改变制造的顺序)。
* 第四步:写客户端代码进行测试
*/
//第一步:创建一个Builder抽象类,规定了这些步骤,具体对象去继承就不会遗漏制造过程。
public abstract class Builder {
    /**
     * builder前轮
     */
    public  abstract  void BuilderFrontWheel();

    /**
     * builder后轮
     */
    public  abstract  void BuilderBackWheel();

    /**
     * 构建框架
     */
    public  abstract  void BuilderFrame();

    /**
     * 构建链子
     */
    public  abstract  void BuilderChain();
}
//第二步:创建一个具体的建造者ConcreteBuilderA去建造一个大车架的自行车,ConcreteBuilderB去建造一个小车架的自行车。
public class ConcreteBuilderA extends Builder{
    /**
     * builder前轮
     */
    @Override
    public void BuilderFrontWheel() {
        System.out.println("制造前轮");
    }

    /**
     * builder后轮
     */
    @Override
    public void BuilderBackWheel() {
        System.out.println("制造后轮");
    }

    /**
     * 构建框架
     */
    @Override
    public void BuilderFrame() {
        System.out.println("制造大车架");
    }

    /**
     * 构建链子
     */
    @Override
    public void BuilderChain() {
        System.out.println("制造链子");
    }
}
public class ConcreteBuilderB extends Builder{
    /**
     * builder前轮
     */
    @Override
    public void BuilderFrontWheel() {
        System.out.println("制造前轮");
    }

    /**
     * builder后轮
     */
    @Override
    public void BuilderBackWheel() {
        System.out.println("制造后轮");
    }

    /**
     * 构建框架
     */
    @Override
    public void BuilderFrame() {
        System.out.println("制造小车架");
    }

    /**
     * 构建链子
     */
    @Override
    public void BuilderChain() {
        System.out.println("制造链子");
    }
}
//第三步:创建一个指导者(Director)
public class Director {
    private Builder builder;
    public Director(Builder builder) {
        this.builder = builder;
    }
    public void createBicycle(){
        builder.BuilderBackWheel();
        builder.BuilderFrontWheel();
        builder.BuilderFrame();
        builder.BuilderChain();
    }
}
//创建客户端代码测试
public class Client {
    public static void main(String[] args) {
        System.out.println("--------------------制造大轮子车--------------------------");
        new Director(new ConcreteBuilderA()).createBicycle();
        System.out.println("--------------------制造小轮子车--------------------------");
        new Director(new ConcreteBuilderB()).createBicycle();
    }
}
//结果
--------------------制造大轮子车--------------------------
制造后轮
制造前轮
制造大车架
制造链子
--------------------制造小轮子车--------------------------
制造后轮
制造前轮
制造小车架
制造链子

以上案例只说明了建造者模式的使用,未创建出具体的自行车类,如果需要封装也很简单,具体代码改变如下:

//Bicycle
public class Bicycle {
    private String frontWheel;
    private String backWheel;
    private String frame;
    private String chain;

    public void setFrontWheel(String frontWheel) {
        this.frontWheel = frontWheel;
    }

    public void setBackWheel(String backWheel) {
        this.backWheel = backWheel;
    }

    public void setChain(String chain) {
        this.chain = chain;
    }

    public void setFrame(String frame) {
        this.frame = frame;
    }

    @Override
    public String toString() {
        return "Bicycle{" +
                "frontWheel='" + frontWheel + '\'' +
                ", backWheel='" + backWheel + '\'' +
                ", frame='" + frame + '\'' +
                ", chain='" + chain + '\'' +
                '}';
    }
}
//Builder
public abstract class Builder {
    protected Bicycle bicycle = new Bicycle();
    /**
     * builder前轮
     */
    public  abstract void builderFrontWheel();

    /**
     * builder后轮
     */
    public  abstract  void builderBackWheel();

    /**
     * 构建框架
     */
    public  abstract  void builderFrame();

    /**
     * 构建链子
     */
    public  abstract  void builderChain();

    public Bicycle getBicycle(){
        return bicycle;
    }
}
//ConcreteBuilderA|B
public class ConcreteBuilderA extends Builder {
    /**
     * builder前轮
     *
     */
    @Override
    public void builderFrontWheel() {
        bicycle.setFrontWheel("前轮");
    }

    /**
     * builder后轮
     *
     */
    @Override
    public void builderBackWheel() {
        bicycle.setBackWheel("后轮");
    }

    /**
     * 构建框架
     */
    @Override
    public void builderFrame() {
        bicycle.setFrame("大车架");
    }

    /**
     * 构建链子
     *
     */
    @Override
    public void builderChain() {
        bicycle.setChain("链子");
    }
}
public class ConcreteBuilderB extends Builder {
    /**
     * builder前轮
     *
     */
    @Override
    public void builderFrontWheel() {
        bicycle.setFrontWheel("前轮");
    }

    /**
     * builder后轮
     *
     */
    @Override
    public void builderBackWheel() {
        bicycle.setBackWheel("后轮");
    }

    /**
     * 构建框架
     */
    @Override
    public void builderFrame() {
        bicycle.setFrame("小车架");
    }

    /**
     * 构建链子
     *
     */
    @Override
    public void builderChain() {
        bicycle.setChain("链子");
    }
}
//Director
public class Director {
    private Builder builder;
    public Director(Builder builder) {
        this.builder = builder;
    }
    public Bicycle buildeBicycle(){
        builder.builderFrontWheel();
        builder.builderBackWheel();
        builder.builderFrame();
        builder.builderChain();
        return builder.getBicycle();
    }
}

//Client
public class Client {
    public static void main(String[] args) {
        System.out.println("--------------------制造大轮子车--------------------------");
        Bicycle bicycleA = new Director(new ConcreteBuilderA()).buildeBicycle();
        System.out.println(bicycleA.toString());
        System.out.println("--------------------制造小轮子车--------------------------");
        Bicycle bicycleB = new Director(new ConcreteBuilderB()).buildeBicycle();
        System.out.println(bicycleB.toString());
    }
}
//结果
--------------------制造大轮子车--------------------------
Bicycle{frontWheel='前轮', backWheel='后轮', frame='大车架', chain='链子'}
--------------------制造小轮子车--------------------------
Bicycle{frontWheel='前轮', backWheel='后轮', frame='小车架', chain='链子'}

Note:如有错误,欢迎指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

w͏l͏j͏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值