JavaScript设计模式_js实现建造者模式

更新日期: 2018-03-28阅读量: 1838标签: 模式

什么是建造者模式

建造者模式:是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象,所谓复合对象就是指某个类具有不同的属性。

具体表现为4个角色

产品(Product):建造的产物
导演(Director):指挥建造的过程,不涉及建造的细节
建造者(Builder):抽象建造过程,规定产品哪些部分需要创建
具体建造者(ConceteBuilder):实现Builder,实现产品各个部分的建造,并提供产品

使用场景:

需要生成的对象有复杂的内部结构,且各部分都会根据需求发生组装变化
缺点:
1、当产品内部非常复杂,需要用大量的具体建造者,导致系统庞大
2、产品要有共同点,范围受限制


下面举个例子:肯德基点餐环节,角色对应分别如下
Product:一餐食物(Meal)
Director:前台销售员(Seller)
Builder:抽象建造者(Builder)
ConceteBuilder:厨师(Cook)


首先实现一些食物

// Food 食物抽象类
class Food {
    constructor() {
        this.name = null;
        this.price = null;
    }
}
// 汉堡
class Burger extends Food {
    constructor() {
        super();
        this.name = '汉堡';
        this.price = 16;
    }
}
// 鸡翅
class ChickenWing extends Food {
    constructor() {
        super();
        this.name = '鸡翅';
        this.price = 12;
    }
}
// 可乐
class Coke extends Food {
    constructor() {
        super();
        this.name = '可乐';
        this.price = 6;
    }
}


产品Product
一桌餐饭可以有任意数量的任意组合

// Product
class Meal {
    constructor() {
        this.foods = [];
    }
    
    addFood(item) {
        this.foods.push(item);
    }
    showPrice() {
        var i = this.foods.length,
            price = 0;
        while(i--) {
            price += this.foods[i].price;
        }

        return price;
    }
}


抽象建造类Builder
规范各部分的建造

// Builder
class Builder {
    cookBurger() {}
    cookWing() {}
    cookCoke() {}
    finishCook() {}
}


具体建造类
厨师负责各个食物的烹饪,并添加到meal里

// ConceteBuilder
class Cook extends Builder {
    constructor() {
        super();
        this.meal = new Meal();
    }

    cookBurger(number) {
        for (var i = 0; i < number; i++) {
            this.meal.addFood(new Burger());
        }
    }
    cookWing(number) {
        for (var i = 0; i < number; i++) {
            this.meal.addFood(new ChickenWing());
        }
    }
    cookCoke(number) {
        for (var i = 0; i < number; i++) {
            this.meal.addFood(new Coke());
        }
    }
    finishCook() {
        return this.meal;
    }
}


导演Director
负责通知厨房需要烹饪啥啥啥。

// Director
class Seller {
    constructor() {
        this.builder = null;
    }

    bindCook(builder) {
        this.builder = builder;
    }
    placeOrder(burgerAmount, wingAmount, cokeAmount) {
        this.builder.cookBurger(burgerAmount);
        this.builder.cookWing(wingAmount);
        this.builder.cookCoke(cokeAmount);

        var meal = this.builder.finishCook();
        console.log('总价:' + meal.showPrice());
        return meal;
    }
}


最后模拟一次下单场景

var seller = new Seller();
var cook = new Cook();
seller.bindCook(cook);
seller.placeOrder(1, 2, 3); // 58


总结:

易于解耦 :将产品本身与产品创建过程进行解耦,可以使用相同的创建过程来得到不同的产品。也就说细节依赖抽象
易于精确控制对象的创建 :将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰
易于拓展 :增加新的具体建造者无需修改原有类库的代码,易于拓展,符合“开闭原则“

来源:https://segmentfault.com/a/1190000014035704
站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

链接: https://www.fly63.com/article/detial/559

如何在代码中应用设计模式

因为我们的项目的需求是永远在变的,为了应对这种变化,使得我们的代码能够轻易的实现解耦和拓展。如果能够保证代码一次写好以后都不会再改变了,那可以想怎么写怎么写了。

js设计模式之单例模式

确保只有一个实例提供全局访问,代理的作用是实现一个实例的逻辑;惰性单例顾名思义就是在我们需要的时候在去创建这个单例

js设计模式之单例模式,javascript如何将一个对象设计成单例

单例模式是我们开发中一个非常典型的设计模式,js单例模式要保证全局只生成唯一实例,提供一个单一的访问入口,单例的对象不同于静态类,我们可以延迟单例对象的初始化,通常这种情况发生在我们需要等待加载创建单例的依赖。

让你的网站支持iOS13 Darkmode 模式的工具

最近iOS13 发布了darkmode模式。虽然本人觉得次此功能呼声大于实际,但作为一个以用户体验为己任的前端,当然不能坐视不管,我们总该做点什么。

javascript 之迭代器

迭代器是一种设计模式,可在容器对象 如 链表、数组上遍历,无需关心容器对象的内存分配的实现细节。简单的理解就是可以一个一个的依次拿到其中的数据,类似一个移动的指针,但是会告诉我们什么时候结束

发布订阅模式与观察者模式

设计模式的定义是:在面向对象软件设计过程中针对特定问题的简洁而优雅的解决方案。通俗一点说,设计模式是在某种场合下对某个问题的一种解决方案。如果再通俗一点说,设计模式就是给面向对象软件开发中的一些好的设计取个名字。

MySQL时间类型和模式

当我在MySQL数据库中尝试插入一条带有时间戳的数据时报错:我们可以发现错误信息提示是时间值错误,但是我们这明显是一个合法的时间点啊。

Js设计模式——命令模式

向某些对象发送请求,但是并不知道被请求的操作具体是什么,所以我们希望以一种松耦合的方式来设计程序,使得请求发送者和接收者之间能够消除彼此之间的耦合关系;而我们的这种松耦合的方式就是命令模式

js责任链模式

多个对象均有机会处理请求,从而解除发送者和接受者之间的耦合关系。这些对象连接成为链式结构,每个节点转发请求,直到有对象处理请求为止。 其核心就是:请求者不必知道是谁哪个节点对象处理的请求

发布订阅和观察者模式的区别

有些人认为观察者模式就是发布订阅模式,实际上观察者模式是包含了订阅发布模式,发布订阅模式只是观察者模式中的一种。观察者模式是观察者和被观察者之间的通信,而发布订阅模式中间增加了一个中转层

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!