1.命令模式
1.1 定义
命令模式(Command): 将请求与实现解耦并封装成独立对象, 从而使不同的请求对客户端的实现参数化.
命令模式是一个高内聚的模式说白了就是将一系列的请求命令封装起来,不直接调用真正执行者的方法, 通过调用具体的请求者来执行对应的方法.这样子比较好扩展.
1.2 作用
- 将动作的请求和动作的实现进行解耦.使得两者可以独立变化.
- 简化了操作对象的复杂性,带来更好的灵活性和可扩展性
使用命令模式可以降低对象之间的耦合度,新的命令可以很容易得加入到系统上,可以非常容易地运行一个组合命令, 通过实现参数化, 可以调用同一方法实现不同的功能.
1.3 应用实例
- 场景一
let cmdList = {
// 绘制一个DIV元素追加到页面上
ctxDiv(width=400,height=400,backgroundColor='#ccc'){
let div = document.createElement('div');
div.style.width = width +'px';
div.style.height = height + 'px';
div.style.backgroundColor = backgroundColor
document.body.append(div)
},
// 绘制一个a标签追加到页面上
ctxA(href, text){
let a = document.createElement('a');
a.href = href;
a.textContent = text
document.body.append(a)
},
// 绘制一个p标签追加到页面上
ctxP(text,color="#f46"){
let p = document.createElement('p');
p.textContent = text;
p.style.color = color
document.body.append(p)
},
// 执行对应的命令
execute(data=[]){
data.forEach(item => {
let { command,params} = item;
// 当存在对应命令方法时,执行对应命令并传递对应的参数
cmdList[command] && cmdList[command](...params)
})
},
// 新增命令
addCmd(key,action){
command[key] = action
},
// 删除命令
removeCmd(key){
Reflect.deleteProperty(cmdList, key)
}
};
cmdList.removeCmd("ctxA")
// 执行命令
cmdList.execute([
{command:'ctxDiv',params:["200","200","red"]},
{command: 'ctxA', params: ["www.baidu.com", "百度云"] },
{ command: 'ctxP', params: ["这是一条文本","red"] }
])
上面的代码我们通过在cmdList定义了三条命令, 即ctxDiv, ctxA,ctxP三个具体进行实际操作的方法, 通过对外暴露的execute方法来请求并执行对应的命令,execute方法接受一个数组参数, 通过这个参数我们可以传入多条命令, 内部通过forEach方法遍历数组, 并通过解构将具体的命令名和对应的参数取取来, 当存在对应的命令时,我们执行对应的命令并传递对应的参数.
总结:命令模式的核心就是将请求和实现解耦并封装成独立对象,具体怎么实现非常灵活, 当系统需要将请求调用者和请求接受者解耦, 使得调用者和接受者不直接交互,使用命令模式就非常合适