-
Notifications
You must be signed in to change notification settings - Fork 260
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c0853c3
commit 0522384
Showing
3 changed files
with
127 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
# 命令模式 | ||
命令模式`Command Pattern`是一种数据驱动的设计模式,其属于行为型模式,别名为动作`Action`模式或事务`Transaction`模式,命令模式将请求以命令的形式包裹在对象中,并传给调用对象,调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象对请求排队或者记录请求日志,以及支持可撤销的操作。 | ||
|
||
## 描述 | ||
在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活。命令模式可以对发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。命令模式也可以用于实现基于事务的系统,一旦执行命令,便会继续保留命令的历史记录,如果最终命令成功执行,那么一切都很好,否则只需遍历历史记录并继续对所有已执行的命令执行撤消即可。 | ||
|
||
### 优点 | ||
* 降低系统的耦合度。 | ||
* 新的命令可以很容易地加入到系统中。 | ||
* 可以比较容易地设计一个命令队列和宏命令(组合命令)。 | ||
* 可以方便地实现对请求的Undo和Redo。 | ||
|
||
### 缺点 | ||
* 使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。 | ||
|
||
### 适用环境 | ||
* 系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。 | ||
* 系统需要在不同的时间指定请求、将请求排队和执行请求。 | ||
* 系统需要支持命令的撤销`Undo`操作和恢复`Redo`操作。 | ||
* 系统需要将一组操作组合在一起,即支持宏命令 | ||
|
||
## 实现 | ||
|
||
```javascript | ||
// 假设我们有一个电灯,我们使用遥控器对其进行控制 | ||
|
||
class Bulb { | ||
turnOn() { | ||
console.log("Bulb has been lit!"); | ||
} | ||
|
||
turnOff() { | ||
console.log("Darkness!"); | ||
} | ||
} | ||
|
||
class Command { | ||
execute(){ | ||
throw new Error("Abstract method cannot be called"); | ||
} | ||
|
||
redo(){ | ||
throw new Error("Abstract method cannot be called"); | ||
} | ||
|
||
undo(){ | ||
throw new Error("Abstract method cannot be called"); | ||
} | ||
} | ||
|
||
class TurnOnCommand extends Command{ | ||
constructor(bulb) { | ||
super(); | ||
this.bulb = bulb; | ||
} | ||
|
||
execute() { | ||
this.bulb.turnOn(); | ||
} | ||
|
||
undo() { | ||
this.bulb.turnOff(); | ||
} | ||
|
||
redo() { | ||
this.execute(); | ||
} | ||
} | ||
|
||
class TurnOffCommand extends Command { | ||
constructor(bulb) { | ||
super(); | ||
this.bulb = bulb; | ||
} | ||
|
||
execute() { | ||
this.bulb.turnOff(); | ||
} | ||
|
||
undo() { | ||
this.bulb.turnOn(); | ||
} | ||
|
||
redo() { | ||
this.execute(); | ||
} | ||
} | ||
|
||
class RemoteControl { | ||
submit(command) { | ||
command.execute(); | ||
} | ||
} | ||
|
||
(function(){ | ||
var bulb = new Bulb(); | ||
|
||
var turnOn = new TurnOnCommand(bulb); | ||
var turnOff = new TurnOffCommand(bulb); | ||
|
||
var remote = new RemoteControl(); | ||
remote.submit(turnOn); // Bulb has been lit! | ||
remote.submit(turnOff); // Darkness! | ||
})(); | ||
``` | ||
|
||
|
||
## 每日一题 | ||
|
||
``` | ||
https://github.com/WindrunnerMax/EveryDay | ||
``` | ||
|
||
## 参考 | ||
|
||
``` | ||
https://www.runoob.com/design-pattern/command-pattern.html | ||
https://github.com/sohamkamani/javascript-design-patterns-for-humans#-command | ||
https://design-patterns.readthedocs.io/zh_CN/latest/behavioral_patterns/command.html | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters