【设计模式】使用中介者模式优化表单交互

2024-04-24 13:44

本文主要是介绍【设计模式】使用中介者模式优化表单交互,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

我们想象一下机场的指挥塔,如果没有指挥塔的存在,每一架飞机要和方圆 100 公里内的所有飞机通信,才能确定航线以及飞行状况,后果是不可想象的。现实中的情况是,每架飞机都只需要和指挥塔通信。指挥塔作为调停者,知道每一架飞机的飞行状况,所以它可以安排所有飞机的起降时间,及时做出航线调整。

什么是中介者模式?

在程序里,也许一个对象会和其他 10 个对象打交道,所以它会保持 10 个对象的引用,并且自己维护与其他对象的交互逻辑。

当程序的规模增大,对象会越来越多,它们之间的关系也越来越复杂,难免会形成网状的交叉引用。

中介者模式-1.png

中介者模式的作用就是解除对象与对象之间的紧耦合关系。增加一个中介者对象后,所有的相关对象都通过中介者对象来通信,而不是互相引用所以当一个对象发生改变时,只需要通知中介者对象即可。

在中介者模式里,对象之间几乎不知道彼此的存在,它们只能通过中介者对象来互相影响对方。

中介者模式-2.png

中介者模式使各个对象之间得以解耦,以中介者和对象之间的一对多关系取代了对象之间的网状多对多关系。

各个对象只需关注自身功能的实现,对象之间的交互关系交给了中介者对象来实现和维护。

示例:要素之间相互影响的商品表单

假设一个商品选择表单有如下功能:

  • 剩余数量受所选颜色和内存影响。
  • 购买数量超过剩余数量时提交按钮置灰。
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><form id="form"><div><label for="color">颜色</label><select name="color" id="color"><option value="red">red</option><option value="blue">blue</option><option value="green">green</option></select></div><div><label for="memory">内存</label><select name="memory" id="memory"><option value="red">2G</option><option value="blue">4G</option><option value="green">8G</option></select></div><div><label for="num">购买数量</label><input name="num" type="number" id="num" /></div><div><span>剩余数量:</span><span id="surplus"></span></div><button id="btn">提交</button></form><script>const form = document.getElementById("form");const numInput = form.num;const colorSelect = form.color;const colorMemory = form.memory;const btn = form.btn;const surplus = document.getElementById("surplus");// 根据参数获取剩余数量const commodityMap = {};function getCommodityNum(color, memory) {const key = `${color}-${memory}`;if (!commodityMap[key]) {commodityMap[key] = Math.floor(Math.random() * 10);}return commodityMap[key];}// 更新剩余数量function updateSurplus() {const num = getCommodityNum(colorSelect.value, colorMemory.value);surplus.innerText = num;}// 更新按钮状态function updateBtnDisabledStatus() {if (Number(surplus.innerText) < Number(numInput.value)) {btn.setAttribute("disabled", true);} else {btn.removeAttribute("disabled");}}numInput.oninput = function () {updateBtnDisabledStatus();};colorSelect.onchange = function () {updateSurplus();updateBtnDisabledStatus();};colorMemory.onchange = function () {updateSurplus();updateBtnDisabledStatus();};btn.onclick = function (e) {const params = {num: numInput.value,color: colorSelect.value,memory: colorMemory.value,};console.log(params);e.preventDefault();};updateSurplus();</script></body>
</html>

最终效果如下:

中介者模式-示例-1.png
中介者模式-示例-2.png

这样的实现方式,需要在每一个表单项的 onchange 事件中维护两种事件:更新按钮状态更新剩余数量

这种写法的弊端在于需要牢记每个表单项之间的关联关系,在后续有变更的情况下要在多处进行修改,同时也产生了一些重复代码。

如果后续需求变动,要再加一个 cpu 的选择,那就要将 onchange 事件处理程序再粘贴一份出来:

// ...
cpuSelect.onchange = function () {updateSurplus();updateBtnDisabledStatus();
};
// ...

用中介者模式优化

引入一个中介者类来集中定义处理程序。

// ...
class Mediator {static change(target) {updateBtnDisabledStatus();if (target != numInput) {updateSurplusText();}}
}// ...
numInput.oninput = function () {Mediator.change(this);
};colorSelect.onchange = function () {Mediator.change(this);
};colorMemory.onchange = function () {Mediator.change(this);
};
// ...

这样改动之后,不需要再在表单项的 onchange 事件中处理 更新按钮状态更新剩余数量,而是只触发 Mediator.change 方法。

Mediator.change 方法中根据触发事件的对象来区分要执行什么操作。

这时如果要加一个 cpu 选择,可以添加如下代码:

// ...
cpuSelect.onchange = function () {Mediator.change(this);
};
// ...

可以看到这样的改动对于整体而言改动较小,并且 cpuSelect 对象不需要关注它的改动会造成什么影响。

总结

中介者模式的优点是解除了对象之间的紧密耦合关系,在新建对象以及新建对象关系时提供更高的可维护性和可扩展性。

它的缺点在于它将对象之间交互的复杂性转移成了中介者对象的复杂性,使得中介者对象经常是巨大的,中介者对象自身往往就是一个难以维护的对象

是否使用中介者模式取决于对象之间的耦合程度,毕竟我们写程序是为了快速完成项目交付生产,而不是堆砌模式和过度设计。

参考

《JavaScript 设计模式与开发实践》

这篇关于【设计模式】使用中介者模式优化表单交互的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/931917

相关文章

C语言中联合体union的使用

本文编辑整理自: http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=179471 一、前言 “联合体”(union)与“结构体”(struct)有一些相似之处。但两者有本质上的不同。在结构体中,各成员有各自的内存空间, 一个结构变量的总长度是各成员长度之和。而在“联合”中,各成员共享一段内存空间, 一个联合变量

Tolua使用笔记(上)

目录   1.准备工作 2.运行例子 01.HelloWorld:在C#中,创建和销毁Lua虚拟机 和 简单调用。 02.ScriptsFromFile:在C#中,对一个lua文件的执行调用 03.CallLuaFunction:在C#中,对lua函数的操作 04.AccessingLuaVariables:在C#中,对lua变量的操作 05.LuaCoroutine:在Lua中,

uniapp接入微信小程序原生代码配置方案(优化版)

uniapp项目需要把微信小程序原生语法的功能代码嵌套过来,无需把原生代码转换为uniapp,可以配置拷贝的方式集成过来 1、拷贝代码包到src目录 2、vue.config.js中配置原生代码包直接拷贝到编译目录中 3、pages.json中配置分包目录,原生入口组件的路径 4、manifest.json中配置分包,使用原生组件 5、需要把原生代码包里的页面修改成组件的方

Vim使用基础篇

本文内容大部分来自 vimtutor,自带的教程的总结。在终端输入vimtutor 即可进入教程。 先总结一下,然后再分别介绍正常模式,插入模式,和可视模式三种模式下的命令。 目录 看完以后的汇总 1.正常模式(Normal模式) 1.移动光标 2.删除 3.【:】输入符 4.撤销 5.替换 6.重复命令【. ; ,】 7.复制粘贴 8.缩进 2.插入模式 INSERT

如何开启和关闭3GB模式

https://jingyan.baidu.com/article/4d58d5414dfc2f9dd4e9c082.html

Lipowerline5.0 雷达电力应用软件下载使用

1.配网数据处理分析 针对配网线路点云数据,优化了分类算法,支持杆塔、导线、交跨线、建筑物、地面点和其他线路的自动分类;一键生成危险点报告和交跨报告;还能生成点云数据采集航线和自主巡检航线。 获取软件安装包联系邮箱:2895356150@qq.com,资源源于网络,本介绍用于学习使用,如有侵权请您联系删除! 2.新增快速版,简洁易上手 支持快速版和专业版切换使用,快速版界面简洁,保留主

如何免费的去使用connectedpapers?

免费使用connectedpapers 1. 打开谷歌浏览器2. 按住ctrl+shift+N,进入无痕模式3. 不需要登录(也就是访客模式)4. 两次用完,关闭无痕模式(继续重复步骤 2 - 4) 1. 打开谷歌浏览器 2. 按住ctrl+shift+N,进入无痕模式 输入网址:https://www.connectedpapers.com/ 3. 不需要登录(也就是

十五.各设计模式总结与对比

1.各设计模式总结与对比 1.1.课程目标 1、 简要分析GoF 23种设计模式和设计原则,做整体认知。 2、 剖析Spirng的编程思想,启发思维,为之后深入学习Spring做铺垫。 3、 了解各设计模式之间的关联,解决设计模式混淆的问题。 1.2.内容定位 1、 掌握设计模式的"道" ,而不只是"术" 2、 道可道非常道,滴水石穿非一日之功,做好长期修炼的准备。 3、 不要为了

十四、观察者模式与访问者模式详解

21.观察者模式 21.1.课程目标 1、 掌握观察者模式和访问者模式的应用场景。 2、 掌握观察者模式在具体业务场景中的应用。 3、 了解访问者模式的双分派。 4、 观察者模式和访问者模式的优、缺点。 21.2.内容定位 1、 有 Swing开发经验的人群更容易理解观察者模式。 2、 访问者模式被称为最复杂的设计模式。 21.3.观察者模式 观 察 者 模 式 ( Obser