命令模式
命令模式中的命令(command)指的是一个执行某些特定事情的指令。
命令模式最常见的应用场景是:有时候需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是什么。此时希望用一种松耦合的方式来设计程序,使得请求发送者和请求接收者能够消除彼此之间的耦合关系。
例如前端开发分为界面开发以及代码逻辑开发两部分,界面开发的同学设计了一个刷新按钮,点击可以执行刷新操作。
1 2 3 4
| <button id="refreshBtn">刷新</button> <script> let refreshBth = document.getElementById('refreshBtn'); </script>
|
但是这时候负责开发实际代码逻辑的同学由于业务比较复杂,因此还没来得及开发完成,此时界面开发的同学不知道如何调用实际的刷新操作。
此时可以利用命令模式,统一规定了命令的执行需要调用 execute 方法。
1 2 3 4 5
| let setCommand = function(button, command){ button.onclick = function(){ command.execute(); } }
|
此时负责代码逻辑的同学直接实现带 execute 功能的对象或函数即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| let ButtonRefresh = { refresh: function(){ console.log('按钮刷新') } }
let RefreshCommand = function(receiver){ return function(){ receiver.refresh(); } }
let refreshCommand = new RefreshCommand(ButtonRefresh);
setCommand(refreshBth, refreshCommand);
|
宏命令
宏命令即执行一系列的名利,例如点外面时候的 下单 -> 做餐 -> 包装 -> 配送 ->取餐 一系列的命令。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| let OrderCommand = { execute: function(){ console.log('下单啦') } }
let CookCommand = { execute: function(){ console.log('做餐啦') } }
let PackCommand = { execute: function(){ console.log('包装啦') } }
let DeliveryCommand = { execute: function(){ console.log('配送啦') } }
let PickCommand = { execute: function(){ console.log('取餐啦') } }
let MacroCommand = function(){ return { commandList: [], add: function(command){ this.commandList.push(command) }, execute: function(){ for(command of this.commandList){ command.execute(); } } } }
let macroCommand = MacroCommand() macroCommand.add(OrderCommand) macroCommand.add(CookCommand) macroCommand.add(PackCommand) macroCommand.add(DeliveryCommand) macroCommand.add(PickCommand)
macroCommand.execute()
|
组合模式
上述一系列的命令可以组合成一些复杂的命令,例如命令直接存在树状结构,此时可以采用组合模式进行命令的组合。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| let MacroCommand = function(){ return { commandList: [], add: function(command){ this.commandList.push(command) }, execute: function(){ for(command of this.commandList){ command.execute(); } } } }
let macroCommand1 = MacroCommand() let macroCommand2 = MacroCommand() let macroCommand3 = MacroCommand() let macroCommand4 = MacroCommand()
macroCommand1.add(macroCommand2) macroCommand2.add(macroCommand3) macroCommand2.add(macroCommand4)
macroCommand1.execute()
|
文件扫描系统
文件系统时典型的树状结构,可以通过文件夹与文件的组合,模拟树状结构。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| class Folder{ constructor(){ this.files = [] }
add(){ this.files.push(...arguments) }
scan(){ for(let file of this.files){ file.scan() } } }
class File{ constructor(name){ this.name = name } add(){ throw new Error('文件不能添加文件') } scan(){ console.log(this.name) } }
let folder1 = new Folder() let folder2 = new Folder() let folder3 = new Folder()
let file1 = new File('文件1') let file2 = new File('文件2') let file3 = new File('文件3') let file4 = new File('文件4')
folder1.add(folder2) folder2.add(folder3) folder2.add(file1, file2) folder3.add(file3, file4)
folder1.scan()
|