设计模式(6):建造者模式

尺有所短,寸有所长;不忘初心,方得始终。

一、建造者模式是什么

建造者模式是一种创建型设计模式,能够分步骤创建复杂对象。该模式允许使用相同的创建代码生成不同类型和形式的对象

最大的特点就是能够让我们分步创建对象

设计模式(6):建造者模式

主要作用:将一个复杂的构建进行分离拆分,使得同样的构建过程可以创建不同的表示。

主要解决:创建由各个部分的子对象用一定的算法构成的复杂对象。

何时使用:一些基本部件不会变,而其组合经常变化的时候。

如何解决:将变与不变分离开。

关键代码:建造者:创建和提供实例,主管:管理建造出来的实例的依赖关系。

二、建造者模式的适用场景

  • 创建的对象具有复杂的内部结构以及对象组成算法独立。

  • 创建的对象内部属性本身相互依赖。

比如:造汽车,无论是什么牌子的汽车都好包含轮胎,发动机、底盘、变速箱、车身等独立子对象组成。这些子对象组合起来才是一个完整的汽车对象

三、建造者模式结构

  • 建造者 (Builder):声明一个接口或抽象类作为抽象建造者,便于扩展,在抽象建造者中声明生成器中通用的产品构造步骤。(一般至少包含一个建造产品的抽象方法,一个是返回产品的抽象方法)

  • 具体建造者 (Concrete Builders) :为抽象建造者提供构造对象过程的不同实现。具体生成器也可以构造不遵循通用接口的产品。

  • 指挥者 (Director) :定义调用构造步骤的顺序, 创建和复用特定的产品配置。

  • 产品 (Products) :由不同生成器最终构造的对象。

  • 客户端 (Client) 必须将某个生成器对象与主管类关联,使用生成器对象完成后续所有的构造任务。

设计模式(6):建造者模式

四、建造者模式实现方式

  • 声明产品类,确定产品属性组成。

  • 声明一个接口或抽象类作为抽象建造者,定义一个返回产品的抽象方法,以及建造产品所需要的抽象方法。

  • 为每个形式的产品创建具体建造者类, 并实现其构造步骤。

  • 声明指挥者类,它可以使用同一生成器对象来封装多种构造产品的方式

  • 在客户端代码会同时创建生成器和主管对象,将生成器对象传递给主管对象进行关联

    只有在所有产品都遵循相同接口的情况下, 构造结果可以直接通过主管类获取。否则客户端应当通过生成器获取构造结果。

五、建造者模式的实现

案例:造汽车,汽车对象由轮胎,发动机、底盘、变速箱、车身五个独立子对象组成。

  • 具体产品

    package com.edwin.design.upupdesign.builder;

    /**
    * 汽车
    */

    public class Car {

    /**
    * 轮胎
    */

    public String tire;
    /**
    * 发动机
    */

    public String engine;
    /**
    * 底盘
    */

    public String chassis;
    /**
    * 变速箱
    */

    public String gearbox;
    /**
    * 车身
    */

    public String body;

    ......get set 方法省略........
    }

  • 抽象建造者

    package com.edwin.design.upupdesign.builder;

    /**
    * 抽象建造者 : 声明生成器中通用的产品构造步骤
    */

    public abstract class Builder {

    /**
    * 生产轮胎
    */

    public abstract void tire();
    /**
    * 生产发动机
    */

    public abstract void engine();
    /**
    * 生产底盘
    */

    public abstract void chassis();
    /**
    * 生产变速箱
    */

    public abstract void gearbox();
    /**
    * 生产车身
    */

    public abstract void body();

    /**
    * 返回产品的抽象方法
    */

    public abstract Car getResult();
    }

  • 具体建造者

    /**
    * 具体建造者 :客车建造者
    */

    public class BusBuilder extends Builder{

    private Car car = new Car();

    @Override
    public void tire() {
    car.setTire("客车的黑色轮胎");
    }

    @Override
    public void engine() {
    car.setEngine("客车的发动机");
    }

    @Override
    public void chassis() {
    car.setChassis("客车的底盘");
    }

    @Override
    public void gearbox() {
    car.setGearbox("客车的变速箱");
    }

    @Override
    public void body() {
    car.setBody("客车的车身");
    }

    @Override
    public Car getResult() {
    return car;
    }
    }

    /**
    * 具体建造者 :越野车建造者
    */

    public class SuvBuilder extends Builder{
    private Car car = new Car();

    @Override
    public void tire() {
    car.setTire("越野车的黑色轮胎");
    }

    @Override
    public void engine() {
    car.setEngine("越野车的发动机");
    }

    @Override
    public void chassis() {
    car.setChassis("越野车的底盘");
    }

    @Override
    public void gearbox() {
    car.setGearbox("越野车的变速箱");
    }

    @Override
    public void body() {
    car.setBody("越野车的车身");
    }

    @Override
    public Car getResult() {
    return car;
    }
    }

  • 指挥者

    /**
    * 指挥者 :定义调用构造步骤的顺序, 创建和复用特定的产品配置。
    */

    public class Director {

    public void construct(Builder builder){
    //定义车子的生产顺序 或者在生产过程中添加其他业务逻辑
    builder.tire();
    builder.body();
    builder.chassis();
    builder.engine();
    builder.gearbox();
    }
    }

  • 客户端

    public static void main(String[] args) throws Exception {
    Director director = new Director();
    Builder busBuilder = new BusBuilder();


    //指挥者用busBuilder方法建造客车
    director.construct(busBuilder);
    Car busCar = busBuilder.getResult();
    System.out.println("----构建的客车对象===>>> :" + JSONObject.toJSON(busCar));

    //指挥者用SuvBuilder方法建造越野车
    Builder suvBuilder = new SuvBuilder();
    director.construct(suvBuilder);
    Car suvCar = suvBuilder.getResult();

    System.out.println("----构建的越野车对象===>>> :" + JSONObject.toJSON(suvCar));
    }
  • 案例输出结果设计模式(6):建造者模式

六、建造者模式的优缺点

  • 优点

    • 客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。

    • 每一个具体建造者都独立,可以方便地替换具体建造者或增加新的具体建造者, 用户使用不同的具体建造者即可得到不同的产品对象

    • 增加新的具体建造者无须修改原有类库的代码,指挥者类针对抽象建造者类编程,系统扩展方便,符合开闭原则。

  • 缺点

    • 当建造者过多时,会产生很多类,难以维护。

    • 产品必须有共同点,范围有限制

    • 若产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。

七、建造者模式和工厂模式的区别

  • 工厂模式用于处理 如何获取实例对象,建造者模式用于处理如何建造实例对象

  • 建造者模式比工厂模式多了一个指挥者 的角色,如果把指挥者的逻辑放在客户端,那么建造者模式剩余的部分就可以看作是一个简单的工厂模式。

  • 职责不同:

    • 建造者模式中的建造者类一般只提供产品类中各个组件的建造,而将具体建造过程交付给指挥类。由指挥类负责将各个组件按照特定的规则组建为产品,然后将组建好的产品交付给客户端
    • 工厂模式是将对象的全部创建过程封装在工厂类中,由工厂类向客户端提供最终的产品

八、总结

建造者模式的使用场合是当创建复杂对象时,把创建对象成员和装配方法分离出来,放在建造者类中去实现,客户端使用该复杂对象时,不用理会它的创建和装配过程,只关心它的表示形式。

原文始发于微信公众号(星河之码):设计模式(6):建造者模式

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/27187.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
半码博客——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!