前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >建造者模式

建造者模式

原创
作者头像
WindRunnerMax
修改2020-10-27 14:22:24
4480
修改2020-10-27 14:22:24
举报
文章被收录于专栏:Czy‘s Blog

建造者模式

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

描述

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

模式结构

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

比较

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

优点

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

缺点

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

实现

代码语言:txt
复制
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
})()

每日一题

代码语言:txt
复制
https://github.com/WindrunnerMax/EveryDay

参考

代码语言:txt
复制
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

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 建造者模式
    • 描述
      • 模式结构
      • 比较
      • 优点
      • 缺点
    • 实现
      • 每日一题
        • 参考
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档