中介者对象践行了最少知识原则,指一个对象尽可能少的了解别的对象,从而尽量减少对象间耦合程度。这样各个对象只需关注自身实现逻辑,对象间的交互关系交由中介者对象来实现和维护。
需求背景:
手机购买页面,在购买流程中,可以选择手机的颜色及输入购买数量,同时页面有两个展示区域,分别向用户展示刚选择好的颜色和数量。还有一个按钮动态显示下一步的操作,我们需要查询该颜色手机对应的库存,如果库存数量少于这次购买的数量,按钮将被禁用并显示库存不足,反之按钮可以点击并显示放入购物车。
代码语言: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>
在实际开发中,还是要注意选择利弊,中介者对象因为包含对象间交互的复杂性,所以维护成本可能也会较高。在实际开发中,最优目的还是要快速完成项目交付,而非过度设计和堆砌模式。有时对象间的耦合也是有必要的,只有当对象间复杂耦合确实已经导致调用与维护难以为继,才考虑用中介者模式。