Javascript设计模式之中介者模式

前言:菜鸡也有梦想,而个人梦想就是进一个真正的互联网大厂。之前学习的时候没有系统的整理,从今天开始要保持每周写博客的习惯,但愿本身能够有所成长。为了培养编程思惟,决定从设计模式开始写起。我是经过读《Javascript设计模式与开发实践》来学习设计模式,而且将知识点和收获记录在博客中。编程

此文仅记录本人阅读《JavaScript设计模式与开发实践》的知识点与想法,感谢做者曾探大大写出这么好的一本书。若有冒犯,请联系本人:markcoder@outlook.com处理,请你们购买正版书籍。设计模式

1.中介者模式介绍

中介者模式的做用就是解除对象与对象之间的紧耦合关系。增长一个中介者对象后,全部的相关对象都经过中介者对象来通讯,而不是互相引用,因此当一个对象发生改变时,只须要通知中介者对象便可。bash

改造后函数

2.代码示例

这里仍是使用书中的例子。学习

假设咱们正在编写一个手机购买的页面,在购买流程中,能够选择手机的颜色以及输入购买数量,同时页面中有两个展现区域,分别向用户展现刚刚选择好的颜色和数量。还有一个按钮动态显示下一步的操做,咱们须要查询该颜色手机对应的库存,若是库存数量少于此次的购买数量,按钮将被禁用而且显示库存不足,反之按钮能够点击而且显示放入购物车。ui

简单切一个页面出来。spa

2.1 不使用中介者模式

接下来将分别监听 colorSelect 的 onchange 事件函数和 numberInput 的 oninput 事件函数,然 后在这两个事件中做出相应处理。设计

let colorSelect = document.querySelector( '#colorSelect' ), 
            numberInput = document.querySelector( '#numberInput' ), 
            colorInfo = document.querySelector( '#colorInfo' ), 
            numberInfo = document.querySelector( '#numberInfo' ), 
            nextBtn = document.querySelector( '#nextBtn' );

const goods = { // 模拟从接口取得手机库存
    "red": 3, 
    "blue": 6 
};

// 监听颜色选择器改变
colorSelect.addEventListener('change', () => {
    let color = colorSelect.value, // 颜色
    number = numberInput.value, // 数量
    stock = goods[ color ]; // 该颜色手机对应的当前库存
    colorInfo.innerHTML = color;

    if ( !color ){ 
        nextBtn.disabled = true; 
        nextBtn.innerHTML = '请选择手机颜色'; 
        return; 
    } 
    if ( ( ( number - 0 ) | 0 ) !== number - 0 ){ // 用户输入的购买数量是否为正整数
        nextBtn.disabled = true; 
        nextBtn.innerHTML = '请输入正确的购买数量'; 
        return; 
    } 
    if ( number > stock ){ // 当前选择数量没有超过库存量
        nextBtn.disabled = true; 
        nextBtn.innerHTML = '库存不足'; 
        return; 
    } 
    nextBtn.disabled = false; 
    nextBtn.innerHTML = '放入购物车';
})

// 监听数量输入框改变
numberInput.addEventListener('change', () => {
    let color = colorSelect.value, // 颜色
        number = numberInput.value, // 数量
        stock = goods[ color ]; // 该颜色手机对应的当前库存
    numberInfo.innerHTML = number;

    if ( !color ){ 
        nextBtn.disabled = true; 
        nextBtn.innerHTML = '请选择手机颜色'; 
        return; 
    } 
    if ( ( ( number - 0 ) | 0 ) !== number - 0 ){ // 输入购买数量是否为正整数
        nextBtn.disabled = true; 
        nextBtn.innerHTML = '请输入正确的购买数量'; 
        return; 
    }
    if ( number > stock ){ // 当前选择数量没有超过库存量
        nextBtn.disabled = true; 
        nextBtn.innerHTML = '库存不足'; 
        return ; 
    } 
    nextBtn.disabled = false; 
    nextBtn.innerHTML = '放入购物车';
})
复制代码

若是这时候,需求增长,又加入了CPU种类,那么又要扩充CPU选择框的函数,若是删除了某一种类的选择,又要深刻到每个函数去修改,很是的麻烦,每一个节点对象都是耦合在一块儿的,改变或者增长任何一个节点对象,都要通知到与其相关的对象。3d

2.2使用中介者模式改写

const goods = { // 模拟从接口取得手机库存
    "red": 3, 
    "blue": 6 
};

const mediator = (() => {
    let colorSelect = document.querySelector( '#colorSelect' ), 
    numberInput = document.querySelector( '#numberInput' ), 
    colorInfo = document.querySelector( '#colorInfo' ), 
    numberInfo = document.querySelector( '#numberInfo' ), 
    nextBtn = document.querySelector( '#nextBtn' );

    return {
        changed: function( obj ){ 
            let color = colorSelect.value, // 颜色
                number = numberInput.value // 数量
            if ( obj === colorSelect ){ // 若是改变的是选择颜色下拉框
                colorInfo.innerHTML = color; 
            }else if ( obj === numberInput ){ // 若是改变的是选择颜色下拉框
                numberInfo.innerHTML = number; 
            } 
            if ( !color ){ 
                nextBtn.disabled = true; 
                nextBtn.innerHTML = '请选择手机颜色'; 
                return; 
            } 
            if ( ( ( number - 0 ) | 0 ) !== number - 0 ){ // 输入购买数量是否为正整数
                nextBtn.disabled = true; 
                nextBtn.innerHTML = '请输入正确的购买数量'; 
                return; 
            } 
            nextBtn.disabled = false; 
            nextBtn.innerHTML = '放入购物车'; 
        }
    }
})();

// 事件函数:
colorSelect.addEventListener('change', () => {
    mediator.changed( colorSelect ); 
}); 
numberInput.addEventListener('input', () => {
    mediator.changed( numberInput ); 
}); 
复制代码

能够想象,某天咱们又要新增一些跟需求相关的节点,好比内存大小,那咱们只须要稍稍改动 mediator 对象便可code

新切一个页面

const goods = { // 模拟从接口取得手机库存
    "red": 3, 
    "blue": 6 
};

const mediator = (() => {
    let colorSelect = document.querySelector( '#colorSelect' ), 
    memorySelect = document.querySelector( '#memorySelect' ), // 新增内存大小
    numberInput = document.querySelector( '#numberInput' ), 
    colorInfo = document.querySelector( '#colorInfo' ), 
    numberInfo = document.querySelector( '#numberInfo' ), 
    nextBtn = document.querySelector( '#nextBtn' );
    return {
        changed: function( obj ){ 
            let color = colorSelect.value, // 颜色
                number = numberInput.value, // 数量
                memory = memorySelect.value
            if ( obj === colorSelect ){ // 若是改变的是选择颜色下拉框
                colorInfo.innerHTML = color; 
            } else if ( obj === numberInput ){ // 若是改变的是选择颜色下拉框
                numberInfo.innerHTML = number; 
            } else if ( obj === memorySelect ){ // 若是改变的是选择内存大小
                memoryInfo.innerHTML = memory; 
            }
            if ( !color ){ 
                nextBtn.disabled = true; 
                nextBtn.innerHTML = '请选择手机颜色'; 
                return; 
            } 
            if ( !memory ){  // 新增内存大小
                nextBtn.disabled = true;  
                nextBtn.innerHTML = '请选择手机内存大小'; 
                return; 
            } 
            if ( ( ( number - 0 ) | 0 ) !== number - 0 ){ // 输入购买数量是否为正整数
                nextBtn.disabled = true; 
                nextBtn.innerHTML = '请输入正确的购买数量'; 
                return; 
            } 
            nextBtn.disabled = false; 
            nextBtn.innerHTML = '放入购物车'; 
        }
    }
})();

// 事件函数:

colorSelect.addEventListener('change', () => {
    mediator.changed( colorSelect ); 
}); 
memorySelect.addEventListener('change', () => {
    mediator.changed( memorySelect ); 
}); 
numberInput.addEventListener('input', () => { // 新增内存大小
    mediator.changed( numberInput ); 
}); 
复制代码

中介者模式能够很是方便地对模块或者对象进行解耦,但对象之间并不是必定须要解耦。在实 际项目中,模块或对象之间有一些依赖关系是很正常的。毕竟咱们写程序是为了快速完成项目交 付生产,而不是堆砌模式和过分设计。关键就在于如何去衡量对象之间的耦合程度。通常来讲, 若是对象之间的复杂耦合确实致使调用和维护出现了困难,并且这些耦合度随项目的变化呈指数 增加曲线,那咱们就能够考虑用中介者模式来重构代码。

相关文章
相关标签/搜索