javascript设计模式九:中介者模式

2019-08-29 13:15:03 浏览数 (1)

中介者对象践行了最少知识原则,指一个对象尽可能少的了解别的对象,从而尽量减少对象间耦合程度。这样各个对象只需关注自身实现逻辑,对象间的交互关系交由中介者对象来实现和维护。

需求背景:

手机购买页面,在购买流程中,可以选择手机的颜色及输入购买数量,同时页面有两个展示区域,分别向用户展示刚选择好的颜色和数量。还有一个按钮动态显示下一步的操作,我们需要查询该颜色手机对应的库存,如果库存数量少于这次购买的数量,按钮将被禁用并显示库存不足,反之按钮可以点击并显示放入购物车。

代码语言:javascript复制
  1<!DOCTYPE html>
  2<html lang="en">
  3<head>
  4    <meta charset="UTF-8">
  5    <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6    <meta http-equiv="X-UA-Compatible" content="ie=edge">
  7    <title>中介者模式 购买商品</title>
  8</head>
  9<body>
 10    选择颜色: 
 11    <select id="colorSelect">
 12        <option value="">请选择</option>
 13        <option value="red">红色</option>
 14        <option value="blue">蓝色</option>
 15    </select>
 16
 17    输入购买数量:
 18    <input type="text" id="numberInput">
 19
 20    您选择了颜色:<div id="colorInfo"></div><br>
 21    您输入了数量:<div id="numberInfo"></div><br>
 22
 23    <button id="nextBtn" disabled>请选择手机颜色和购买数量</button>
 24
 25</body>
 26<script>
 27
 28// 最初级的写法
 29var colorSelect = document.getElementById('colorSelect'),
 30    numberInput = document.getElementById('numberInput'),
 31    colorInfo = document.getElementById('colorInfo'),
 32    numberInfo = document.getElementById('numberInfo'),
 33    nextBtn = document.getElementById('nextBtn');
 34
 35var goods = {
 36    'red': 3,
 37    'blue': 6
 38}
 39
 40colorSelect.onchange = function(){
 41    var color = this.value,
 42        number = numberInput.value,
 43        stock = goods[color]
 44
 45    colorInfo.innerHTML = color;
 46
 47    if(!color){
 48        nextBtn.disabled = true;
 49        nextBtn.innerHTML = '请选择手机颜色';
 50        return;
 51    }
 52
 53    if( ( (number-0) | 0 ) !== number-0 ){      //用户输入的购买数量是否为正整数
 54        nextBtn.disabled = true;
 55        nextBtn.innerHTML = '请输入正确的购买数量';
 56        return;
 57    }
 58
 59    if(number > stock){     //当前选择数量大于库存量
 60        nextBtn.disabled = true;
 61        nextBtn.innerHTML = '库存不足';
 62        return;
 63    }
 64
 65    nextBtn.disabled = false;
 66    nextBtn.innerHTML = '放入购物车';
 67}
 68
 69numberInput.oninput = function(){
 70    var color = colorSelect.value,
 71        number = this.value,
 72        stock = goods[color]
 73
 74    colorInfo.innerHTML = color;
 75
 76    if(!color){
 77        nextBtn.disabled = true;
 78        nextBtn.innerHTML = '请选择手机颜色';
 79        return;
 80    }
 81
 82    if( ( (number-0) | 0 ) !== number-0 ){      //用户输入的购买数量是否为正整数
 83        nextBtn.disabled = true;
 84        nextBtn.innerHTML = '请输入正确的购买数量';
 85        return;
 86    }
 87
 88    if(number > stock){     //当前选择数量大于库存量
 89        nextBtn.disabled = true;
 90        nextBtn.innerHTML = '库存不足';
 91        return;
 92    }
 93
 94    nextBtn.disabled = false;
 95    nextBtn.innerHTML = '放入购物车';
 96}
 97
 98
 99</script>
100</html>

在上个示例中,对象间联系高度耦合,只是两个输入框还好,但如果有多个的话,相互联系就非常复杂了,此时就要考虑用到中介者模式。

代码语言:javascript复制
  1<!DOCTYPE html>
  2<html lang="en">
  3<head>
  4    <meta charset="UTF-8">
  5    <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6    <meta http-equiv="X-UA-Compatible" content="ie=edge">
  7    <title>中介者模式 购买商品</title>
  8</head>
  9<body>
 10    选择颜色: 
 11    <select id="colorSelect">
 12        <option value="">请选择</option>
 13        <option value="red">红色</option>
 14        <option value="blue">蓝色</option>
 15    </select>
 16
 17    选择内存: 
 18    <select id="memorySelect">
 19        <option value="">请选择</option>
 20        <option value="32G">32G</option>
 21        <option value="16G">16G</option>
 22    </select>
 23
 24    输入购买数量:
 25    <input type="text" id="numberInput">
 26
 27    您选择了颜色:<div id="colorInfo"></div><br>
 28    您选择了内存:<div id="memoryInfo"></div><br>
 29    您输入了数量:<div id="numberInfo"></div><br>
 30
 31    <button id="nextBtn" disabled>请选择手机颜色、内存和购买数量</button>
 32</body>
 33<script>
 34    var goods = {
 35        'red|32G': 3,
 36        'red|16G': 0,
 37        'blue|32G': 1,
 38        'blue|16G': 6
 39    }
 40
 41    //引入中介者
 42    var mediator = (function(){
 43        var colorSelect = document.getElementById('colorSelect'),
 44            memorySelect = document.getElementById('memorySelect'),
 45            numberInput = document.getElementById('numberInput'),
 46            colorInfo = document.getElementById('colorInfo'),
 47            memoryInfo = document.getElementById('memoryInfo'),
 48            numberInfo = document.getElementById('numberInfo'),
 49            nextBtn = document.getElementById('nextBtn');
 50
 51        return {
 52            changed: function(obj){
 53                var color = colorSelect.value,
 54                    memory = memorySelect.value,
 55                    number = numberInput.value,
 56                    stock = goods[color   '|'   memory];
 57
 58                if(obj == colorSelect){      //如果改变的是选择颜色下拉框
 59                    colorInfo.innerHTML = color;
 60                }else if(obj == memorySelect){
 61                    memoryInfo.innerHTML = memory;
 62                }else if(obj == numberInput){
 63                    numberInfo.innerHTML = number;
 64                }
 65
 66                if(!color){
 67                    nextBtn.disabled = true;
 68                    nextBtn.innerHTML = '请选择手机颜色';
 69                    return;
 70                }
 71
 72                if(!memory){
 73                    nextBtn.disabled = true;
 74                    nextBtn.innerHTML = '请选择手机内存';
 75                    return;
 76                }
 77
 78                if(!number){
 79                    nextBtn.disabled = true;
 80                    nextBtn.innerHTML = '请填写手机数量';
 81                    return;
 82                }
 83
 84                if( ( (number-0) | 0 ) !== number-0 ){      //用户输入的购买数量是否为正整数
 85                    nextBtn.disabled = true;
 86                    nextBtn.innerHTML = '请输入正确的购买数量';
 87                    return;
 88                }
 89
 90                if(number > stock){     //当前选择数量大于库存量
 91                    nextBtn.disabled = true;
 92                    nextBtn.innerHTML = '库存不足';
 93                    return;
 94                }
 95
 96                nextBtn.disabled = false;
 97                nextBtn.innerHTML = '放入购物车';
 98            }
 99        }
100    })()
101
102    colorSelect.onchange = function(){
103        mediator.changed(this)
104    }
105
106    memorySelect.onchange = function(){
107        mediator.changed(this)
108    }
109
110    numberInput.oninput = function(){
111        mediator.changed(this)
112    }
113
114    //以后如果想要再增加选项,如手机CPU之类的,只需在中介者对象里加上相应配置即可。
115</script>
116</html>

在实际开发中,还是要注意选择利弊,中介者对象因为包含对象间交互的复杂性,所以维护成本可能也会较高。在实际开发中,最优目的还是要快速完成项目交付,而非过度设计和堆砌模式。有时对象间的耦合也是有必要的,只有当对象间复杂耦合确实已经导致调用与维护难以为继,才考虑用中介者模式。

0 人点赞