前言:菜鸡也有梦想,而个人梦想就是进一个真正的互联网大厂。之前学习的时候没有系统的整理,从今天开始要保持每周写博客的习惯,但愿本身能够有所成长。为了培养编程思惟,决定从设计模式开始写起。我是经过读《Javascript设计模式与开发实践》来学习设计模式,而且将知识点和收获记录在博客中。编程
此文仅记录本人阅读《JavaScript设计模式与开发实践》的知识点与想法,感谢做者曾探大大写出这么好的一本书。若有冒犯,请联系本人:markcoder@outlook.com处理,请你们购买正版书籍。设计模式
中介者模式的做用就是解除对象与对象之间的紧耦合关系。增长一个中介者对象后,全部的相关对象都经过中介者对象来通讯,而不是互相引用,因此当一个对象发生改变时,只须要通知中介者对象便可。bash
改造后函数
这里仍是使用书中的例子。学习
假设咱们正在编写一个手机购买的页面,在购买流程中,能够选择手机的颜色以及输入购买数量,同时页面中有两个展现区域,分别向用户展现刚刚选择好的颜色和数量。还有一个按钮动态显示下一步的操做,咱们须要查询该颜色手机对应的库存,若是库存数量少于此次的购买数量,按钮将被禁用而且显示库存不足,反之按钮能够点击而且显示放入购物车。ui
简单切一个页面出来。spa
接下来将分别监听 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
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 );
});
复制代码
中介者模式能够很是方便地对模块或者对象进行解耦,但对象之间并不是必定须要解耦。在实 际项目中,模块或对象之间有一些依赖关系是很正常的。毕竟咱们写程序是为了快速完成项目交 付生产,而不是堆砌模式和过分设计。关键就在于如何去衡量对象之间的耦合程度。通常来讲, 若是对象之间的复杂耦合确实致使调用和维护出现了困难,并且这些耦合度随项目的变化呈指数 增加曲线,那咱们就能够考虑用中介者模式来重构代码。