原创

建造者模式

建造者模式

建造者模式Builder Pattern又可以称为生成器模式,是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示,建造者模式属于对象创建型模式。

描述

建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。

模式结构

  • Builder: 抽象建造者,引入抽象建造者的目的,是将建造的具体过程交与它的子类来实现。这样更容易扩展。一般至少会有两个抽象方法,一个用来建造产品,一个是用来返回产品。
  • ConcreteBuilder: 具体建造者,实现抽象类的所有未实现的方法,具体来说一般是两项任务:组建产品、返回组建好的产品。
  • Director: 指挥者,负责调用适当的建造者来组建产品,指挥者一般不与产品类发生依赖关系,与指挥者直接交互的是建造者类,一般来说指挥者被用来封装程序中易变的部分。
  • Product: 产品角色,一般是一个较为复杂的对象,产品类可以是由一个抽象类与它的不同实现组成,也可以是由多个抽象类与他们的实现组成。

比较

  • 与抽象工厂模式相比,建造者模式返回一个组装好的完整产品,而抽象工厂模式返回一系列相关的产品,这些产品位于不同的产品等级结构,构成了一个产品族。
  • 在抽象工厂模式中,客户端实例化工厂类,然后调用工厂方法获取所需产品对象,而在建造者模式中,客户端可以不直接调用建造者的相关方法,而是通过指挥者类来指导如何生成对象,包括对象的组装过程和建造步骤,它侧重于一步步构造一个复杂对象,返回一个完整的对象。
  • 如果将抽象工厂模式看成汽车配件生产工厂,生产一个产品族的产品,那么建造者模式就是一个汽车组装工厂 ,通过对部件的组装可以返回一辆完整的汽车。

优点

  • 在建造者模式中, 客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
  • 每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者, 用户使用不同的具体建造者即可得到不同的产品对象 。
  • 可以更加精细地控制产品的创建过程,将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。
  • 增加新的具体建造者无须修改原有类库的代码,指挥者类针对抽象建造者类编程,系统扩展方便,符合开闭原则。

缺点

  • 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
  • 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。

实现

class Product{ // 具体产品
    constructor(){
        this.name = null;
        this.type = null;
    }
    setName(name){
        this.name = name;
    }
    setType(type){
        this.type = type;
    }
    showProduct(){
        console.log("name:", this.name);
        console.log("type:", this.type);
    }
}

class Builder{ // 抽象建造者
    setPart(name, type){
        throw new Error("Abstract method cannot be called");
    }
    getProduct(){
        throw new Error("Abstract method cannot be called");
    }
}

class ConcreteBuilder extends Builder{ // 实体建造者
    constructor(){
        super();
        this.product = new Product();
    }
    build(name, type){
        this.product.setName(name);
        this.product.setType(type);
    }
    getProduct(){
        return this.product;
    }
}

class Director{ // 指挥者
    constructor(){
        this.builder = new ConcreteBuilder();
    }
    getProductA(){
        this.builder.build("A", "TypeA");
        return this.builder.getProduct();
    }

    getProductB(){
        this.builder.build("B", "TypeB");
        return this.builder.getProduct();
    }
}

(function() {
    var director = new Director();
    var productA = director.getProductA();
    productA.showProduct(); // name: A type: TypeA
    var director = new Director();
    var productB = director.getProductB();
    productB.showProduct(); // name: B type: TypeB
})()

每日一题

https://github.com/WindrunnerMax/EveryDay

参考

https://www.runoob.com/design-pattern/builder-pattern.html
https://wiki.jikexueyuan.com/project/java-design-pattern/builder-pattern.html
https://design-patterns.readthedocs.io/zh_CN/latest/creational_patterns/builder.html

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Canvas基础

    HTML5中引入<canvas>标签,用于图形的绘制,<canvas>为图形的绘制提供了画布,是图形容器,具体的图形绘制由JavaScript来完成。

    WindrunnerMax
  • 浏览器窗口间通信

    浏览器多个标签页窗口间通信,主要是指的同源的多个页面间的通信,主要方法有本地存储通信、Web Worker通信、Web Socket通信。

    WindrunnerMax
  • React中JSX的理解

    JSX是快速生成react元素的一种语法,实际是React.createElement(component, props, ...children)的语法糖,同...

    WindrunnerMax
  • 动手编写你的第一个 Flutter 应用

    我将带领大家尝试编写一个 Flutter 应用,感受一下 Flutter 开发的语法特点和运行效率。

    CSDN技术头条
  • 深入理解javascript中的继承机制(4)多继承寄生式继承借用构造函数借用构造函数并且复制原型以上

    我们知道多继承是面向对象的语言中比较纠结的一个问题,有好处也存在缺陷。这方面我们不多讨论。就javascript而言,要实现多继承是比较简单的,因为javasc...

    desperate633
  • Django 学习笔记之模型高级用法(上)

    前面有两篇文章简单介绍 Django 的模型,这一部分算是基础知识。我自己近期也总做了下总结,将花大概两篇的篇幅来分享下模型的一些高级用法。

    猴哥yuri
  • Raw use of parameterized class 'Future'

    警告:Raw use of parameterized class 'Future' Inspection info: Reports any uses of ...

    早安嵩骏
  • Vue引发的getter和setter

    看着文档研究了一下vue的双向数据绑定,打印出Vue实例下的data对象里的属性时,发现了一个有趣的事情: ? 它的每个属性都有两个相对应的get和set方法,...

    李文杨
  • call、apply和bind的区别

    call() 方法调用一个函数, 其具有一个指定的this值和分别地提供的参数(参数的列表)。

    挥刀北上
  • vue使用canvas签名之清空和保存

      在一些项目业务中,经常会使用到画板,让用户自己去写/画一些东西做标示,比如说在线签电子合约、签名等,在上两篇博客中,已经解决了PC端和移动端的Canvas签...

    流眸

扫码关注云+社区

领取腾讯云代金券