中介者模式
解除对象与对象之间的紧耦合关系,就叫做中介者模式。
使用场景
比如我们要做一个购买手机的页面,正常的购买流程是:选择了储存容量和套餐类型之后,才会展示手机价格。
例子:
<label>储存容量:</label>
<select id="setStorage">
<option value="-">——</option>
<option value="8+128">8+128G</option>
<option value="8+256">8+256G</option>
</select>
<br />
<label>套餐类型:</label>
<select id="setMeal">
<option value="-">——</option>
<option value="normal">官方标配</option>
<option value="one">套餐一</option>
</select>
<br />
<br />
<span style="color: red;"></span>
<p>价格:<strong></strong></p>
<script>
/**
* 8+128G 官方标配 2999
* 8+128G 套餐一 3199
* 8+256G 官方标配 3999
* 8+256G 套餐一 4199
*/
const telephones = [
{ storageType: '8+128', mealType: 'normal', price: '2999' },
{ storageType: '8+128', mealType: 'one', price: '3199' },
{ storageType: '8+256', mealType: 'normal', price: '3999' },
{ storageType: '8+256', mealType: 'one', price: '4199' },
];
const storage = document.querySelector('#setStorage');
const meal = document.querySelector('#setMeal');
const message = document.querySelector('span');
const price = document.querySelector('strong');
// 监听‘储存容量’事件处理程序
storage.addEventListener('change', () => {
const storageValue = storage.value;
const mealValue = meal.value;
if (storageValue === '-') {
message.innerHTML = '请选择储存容量!';
price.innerHTML = '';
return false;
}
if (mealValue === '-') {
message.innerHTML = '请选择套餐类型!';
price.innerHTML = '';
return false;
}
const _arr = telephones
.filter((item) => {
return item.storageType === storageValue;
})
.filter((item) => {
return item.mealType === mealValue;
});
message.innerHTML = '';
price.innerHTML = _arr[0]['price'];
});
// 监听‘套餐类型’事件处理程序
meal.addEventListener('change', () => {
const storageValue = storage.value;
const mealValue = meal.value;
if (storageValue === '-') {
message.innerHTML = '请选择储存容量!';
price.innerHTML = '';
return false;
}
if (mealValue === '-') {
message.innerHTML = '请选择套餐类型!';
price.innerHTML = '';
return false;
}
const _arr = telephones
.filter((item) => {
return item.storageType === storageValue;
})
.filter((item) => {
return item.mealType === mealValue;
});
message.innerHTML = '';
price.innerHTML = _arr[0]['price'];
});
</script>
上面的例子中,尽管我们实现了功能,但是两个下拉框的联系很密切,试想,如果此时又增加了一个下拉框,代表手机的颜色,那么原有的两个事件处理程序,都要面临修改。
此时,就比较适合引入中介者模式,让两个下拉框解耦,而它们的依赖关系交由中介者去维护。
例子:
<label>储存容量:</label>
<select id="setStorage">
<option value="-">——</option>
<option value="8+128">8+128G</option>
<option value="8+256">8+256G</option>
</select>
<br />
<label>套餐类型:</label>
<select id="setMeal">
<option value="-">——</option>
<option value="normal">官方标配</option>
<option value="one">套餐一</option>
</select>
<br />
<br />
<span style="color: red;"></span>
<p>价格:<strong></strong></p>
<script>
/**
* 8+128G 官方标配 2999
* 8+128G 套餐一 3199
* 8+256G 官方标配 3999
* 8+256G 套餐一 4199
*/
const telephones = [
{ storageType: '8+128', mealType: 'normal', price: '2999' },
{ storageType: '8+128', mealType: 'one', price: '3199' },
{ storageType: '8+256', mealType: 'normal', price: '3999' },
{ storageType: '8+256', mealType: 'one', price: '4199' },
];
const storage = document.querySelector('#setStorage');
const meal = document.querySelector('#setMeal');
const message = document.querySelector('span');
const price = document.querySelector('strong');
const Mediator = (() => {
const changed = () => {
const storageValue = storage.value;
const mealValue = meal.value;
if (storageValue === '-') {
message.innerHTML = '请选择储存容量!';
price.innerHTML = '';
return false;
}
if (mealValue === '-') {
message.innerHTML = '请选择套餐类型!';
price.innerHTML = '';
return false;
}
const _arr = telephones
.filter((item) => {
return item.storageType === storageValue;
})
.filter((item) => {
return item.mealType === mealValue;
});
message.innerHTML = '';
price.innerHTML = _arr[0]['price'];
};
return { changed };
})();
// 监听‘储存容量’事件处理程序
storage.addEventListener('change', () => {
Mediator.changed();
});
// 监听‘套餐类型’事件处理程序
meal.addEventListener('change', () => {
Mediator.changed();
});
</script>
重构后的代码,无论是新增下拉框还是修改下拉框,我们仅仅需要改动中介者方法里的代码即可。
如有错误,欢迎指正,本人不胜感激。
打开App,阅读手记