forked from me115/design_patterns
-
Notifications
You must be signed in to change notification settings - Fork 0
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
Showing
27 changed files
with
2,010 additions
and
145 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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,161 @@ | ||
.. _command: | ||
|
||
命令模式 | ||
==================== | ||
|
||
.. contents:: 目录 | ||
|
||
模式动机 | ||
-------------------- | ||
在软件设计中,我们经常需要向某些对象发送请求,但 | ||
是并不知道请求的接收者是谁,也不知道被请求的操作 | ||
是哪个,我们只需在程序运行时指定具体的请求接收者 | ||
即可,此时,可以使用命令模式来进行设计,使得请求 | ||
发送者与请求接收者消除彼此之间的耦合,让对象之间 | ||
的调用关系更加灵活。 | ||
|
||
命令模式可以对发送者和接收者完全解耦,发送者与接 | ||
收者之间没有直接引用关系,发送请求的对象只需要知 | ||
道如何发送请求,而不必知道如何完成请求。这就是命 | ||
令模式的模式动机。 | ||
|
||
模式定义 | ||
-------------------- | ||
命令模式(Command Pattern):将一个请求封装为一 | ||
个对象,从而使我们可用不同的请求对客户进行参数化; | ||
对请求排队或者记录请求日志,以及支持可撤销的操作。 | ||
命令模式是一种对象行为型模式,其别名为动作 | ||
(Action)模式或事务(Transaction)模式。 | ||
|
||
|
||
|
||
模式结构 | ||
-------------------- | ||
命令模式包含如下角色: | ||
? Command: 抽象命令类 | ||
? ConcreteCommand: 具体命令类 | ||
? Invoker: 调用者 | ||
? Receiver: 接收者 | ||
? Client:客户类 | ||
|
||
|
||
.. image:: /_static/SimpleFactory.jpg | ||
|
||
|
||
时序图 | ||
-------------------- | ||
.. image:: /_static/seq_SimpleFactory.jpg | ||
|
||
代码分析 | ||
-------------------- | ||
.. literalinclude:: /code/SimpleFactory/Factory.cpp | ||
:language: cpp | ||
:linenos: | ||
:lines: 1-10,24- | ||
:emphasize-lines: 12-19 | ||
|
||
|
||
|
||
模式分析 | ||
-------------------- | ||
命令模式的本质是对命令进行封装,将发出命令的责任和执行 | ||
命令的责任分割开。 | ||
?每一个命令都是一个操作:请求的一方发出请求,要求执行一 | ||
个操作;接收的一方收到请求,并执行操作。 | ||
?命令模式允许请求的一方和接收的一方独立开来,使得请求的 | ||
一方不必知道接收请求的一方的接口,更不必知道请求是怎么 | ||
被接收,以及操作是否被执行、何时被执行,以及是怎么被执 | ||
行的。 | ||
?命令模式使请求本身成为一个对象,这个对象和其他 | ||
对象一样可以被存储和传递。 | ||
?命令模式的关键在于引入了抽象命令接口,且发送者 | ||
针对抽象命令接口编程,只有实现了抽象命令接口的 | ||
具体命令才能与接收者相关联。 | ||
|
||
|
||
|
||
实例 | ||
-------------------- | ||
实例一:电视机遥控器 | ||
? 电视机是请求的接收者,遥控器是请求的发送者,遥 | ||
控器上有一些按钮,不同的按钮对应电视机的不同操 | ||
作。抽象命令角色由一个命令接口来扮演,有三个具 | ||
体的命令类实现了抽象命令接口,这三个具体命令类 | ||
分别代表三种操作:打开电视机、关闭电视机和切换 | ||
频道。显然,电视机遥控器就是一个典型的命令模式 | ||
应用实例。 | ||
|
||
|
||
优点 | ||
-------------------- | ||
命令模式的优点 | ||
? 降低系统的耦合度。 | ||
? 新的命令可以很容易地加入到系统中。 | ||
? 可以比较容易地设计一个命令队列和宏命令(组合命 | ||
令)。 | ||
? 可以方便地实现对请求的Undo和Redo。 | ||
|
||
|
||
缺点 | ||
-------------------- | ||
命令模式的缺点 | ||
? 使用命令模式可能会导致某些系统有过多的具体命令 | ||
类。因为针对每一个命令都需要设计一个具体命令类, | ||
因此某些系统可能需要大量具体命令类,这将影响命 | ||
令模式的使用。 | ||
|
||
|
||
适用环境 | ||
-------------------- | ||
?在以下情况下可以使用命令模式: | ||
? 系统需要将请求调用者和请求接收者解耦,使得调用者和 | ||
接收者不直接交互。 | ||
? 系统需要在不同的时间指定请求、将请求排队和执行请求。 | ||
? 系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。 | ||
? 系统需要将一组操作组合在一起,即支持宏命令 | ||
|
||
|
||
模式应用 | ||
-------------------- | ||
很多系统都提供了宏命令功能,如UNIX平台下的 | ||
Shell编程,可以将多条命令封装在一个命令对象中, | ||
只需要一条简单的命令即可执行一个命令序列,这也 | ||
是命令模式的应用实例之一。 | ||
|
||
|
||
模式扩展 | ||
-------------------- | ||
宏命令又称为组合命令,它是命令模式和组合模式联用 | ||
的产物。 | ||
?宏命令也是一个具体命令,不过它包含了对其他命令对 | ||
象的引用,在调用宏命令的execute()方法时,将递归 | ||
调用它所包含的每个成员命令的execute()方法,一个 | ||
宏命令的成员对象可以是简单命令,还可以继续是宏命 | ||
令。执行一个宏命令将执行多个具体命令,从而实现对 | ||
命令的批处理 | ||
|
||
总结 | ||
-------------------- | ||
在命令模式中,将一个请求封装为一个对象,从而使我们可用不同的 | ||
请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可 | ||
撤销的操作。命令模式是一种对象行为型模式,其别名为动作模式或 | ||
事务模式。 | ||
? 命令模式包含四个角色:抽象命令类中声明了用于执行请求的execute() | ||
等方法,通过这些方法可以调用请求接收者的相关操作;具体命令类 | ||
是抽象命令类的子类,实现了在抽象命令类中声明的方法,它对应具 | ||
体的接收者对象,将接收者对象的动作绑定其中;调用者即请求的发 | ||
送者,又称为请求者,它通过命令对象来执行请求;接收者执行与请 | ||
求相关的操作,它具体实现对请求的业务处理。 | ||
- 命令模式的本质是对命令进行封装,将发出命令的责任和执行命 | ||
令的责任分割开。命令模式使请求本身成为一个对象,这个对象 | ||
和其他对象一样可以被存储和传递。 | ||
? 命令模式的主要优点在于降低系统的耦合度,增加新的命令很方 | ||
便,而且可以比较容易地设计一个命令队列和宏命令,并方便地 | ||
实现对请求的撤销和恢复;其主要缺点在于可能会导致某些系统 | ||
有过多的具体命令类。 | ||
? 命令模式适用情况包括:需要将请求调用者和请求接收者解耦, | ||
使得调用者和接收者不直接交互;需要在不同的时间指定请求、 | ||
将请求排队和执行请求;需要支持命令的撤销操作和恢复操作; | ||
需要将一组操作组合在一起,即支持宏命令。 | ||
|
||
|
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,178 @@ | ||
.. _mediator: | ||
|
||
中介者模式 | ||
==================== | ||
|
||
.. contents:: 目录 | ||
|
||
模式动机 | ||
-------------------- | ||
- 在用户与用户直接聊天的设计方案中,用户对象之间存在很强的关 | ||
联性,将导致系统出现如下问题: | ||
? 系统结构复杂:对象之间存在大量的相互关联和调用,若有一个对象 | ||
发生变化,则需要跟踪和该对象关联的其他所有对象,并进行适当处 | ||
理。 | ||
? 对象可重用性差:由于一个对象和其他对象具有很强的关联,若没有 | ||
其他对象的支持,一个对象很难被另一个系统或模块重用,这些对象 | ||
表现出来更像一个不可分割的整体,职责较为混乱。 | ||
? 系统扩展性低:增加一个新的对象需要在原有相关对象上增加引用, | ||
增加新的引用关系也需要调整原有对象,系统耦合度很高,对象操作 | ||
很不灵活,扩展性差。 | ||
|
||
- 在面向对象的软件设计与开发过程中,根据“单一职责 | ||
原则”,我们应该尽量将对象细化,使其只负责或呈现 | ||
单一的职责。 | ||
- 对于一个模块,可能由很多对象构成,而且这些对象之 | ||
间可能存在相互的引用,为了减少对象两两之间复杂的 | ||
引用关系,使之成为一个松耦合的系统,我们需要使用 | ||
中介者模式,这就是中介者模式的模式动机。 | ||
|
||
|
||
模式定义 | ||
-------------------- | ||
中介者模式(Mediator Pattern)定义:用一个中介对 | ||
象来封装一系列的对象交互,中介者使各对象不需要显 | ||
式地相互引用,从而使其耦合松散,而且可以独立地改 | ||
变它们之间的交互。中介者模式又称为调停者模式,它 | ||
是一种对象行为型模式。 | ||
|
||
|
||
模式结构 | ||
-------------------- | ||
中介者模式包含如下角色: | ||
? Mediator: 抽象中介者 | ||
? ConcreteMediator: 具体中介者 | ||
? Colleague: 抽象同事类 | ||
? ConcreteColleague: 具体同事类 | ||
|
||
|
||
.. image:: /_static/SimpleFactory.jpg | ||
|
||
|
||
时序图 | ||
-------------------- | ||
.. image:: /_static/seq_SimpleFactory.jpg | ||
|
||
代码分析 | ||
-------------------- | ||
.. literalinclude:: /code/SimpleFactory/Factory.cpp | ||
:language: cpp | ||
:linenos: | ||
:lines: 1-10,24- | ||
:emphasize-lines: 12-19 | ||
|
||
|
||
|
||
模式分析 | ||
-------------------- | ||
中介者模式可以使对象之间的关系数量急剧减少: | ||
|
||
中介者承担两方面的职责: | ||
? 中转作用(结构性):通过中介者提供的中转作用,各个同 | ||
事对象就不再需要显式引用其他同事,当需要和其他同事进 | ||
行通信时,通过中介者即可。该中转作用属于中介者在结构 | ||
上的支持。 | ||
? 协调作用(行为性):中介者可以更进一步的对同事之间的 | ||
关系进行封装,同事可以一致地和中介者进行交互,而不需 | ||
要指明中介者需要具体怎么做,中介者根据封装在自身内部 | ||
的协调逻辑,对同事的请求进行进一步处理,将同事成员之 | ||
间的关系行为进行分离和封装。该协调作用属于中介者在行 | ||
为上的支持。 | ||
|
||
|
||
实例 | ||
-------------------- | ||
实例:虚拟聊天室 | ||
? 某论坛系统欲增加一个虚拟聊天室,允许论坛会员通过该 | ||
聊天室进行信息交流,普通会员(CommonMember)可以给 | ||
其他会员发送文本信息,钻石会员(DiamondMember)既可 | ||
以给其他会员发送文本信息,还可以发送图片信息。该聊 | ||
天室可以对不雅字符进行过滤,如“日”等字符;还可以 | ||
对发送的图片大小进行控制。用中介者模式设计该虚拟聊 | ||
天室。 | ||
|
||
|
||
优点 | ||
-------------------- | ||
中介者模式的优点 | ||
? 简化了对象之间的交互。 | ||
? 将各同事解耦。 | ||
? 减少子类生成。 | ||
? 可以简化各同事类的设计和实现。 | ||
|
||
|
||
缺点 | ||
-------------------- | ||
中介者模式的缺点 | ||
? 在具体中介者类中包含了同事之间的交互细节,可能 | ||
会导致具体中介者类非常复杂,使得系统难以维护。 | ||
|
||
|
||
适用环境 | ||
-------------------- | ||
在以下情况下可以使用中介者模式: | ||
? 系统中对象之间存在复杂的引用关系,产生的相互依赖关系结 | ||
构混乱且难以理解。 | ||
? 一个对象由于引用了其他很多对象并且直接和这些对象通信, | ||
导致难以复用该对象。 | ||
? 想通过一个中间类来封装多个类中的行为,而又不想生成太多 | ||
的子类。可以通过引入中介者类来实现,在中介者中定义对象 | ||
交互的公共行为,如果需要改变行为则可以增加新的中介者类。 | ||
|
||
|
||
模式应用 | ||
-------------------- | ||
MVC架构中控制器 | ||
Controller 作为一种中介者,它负责控制视图对象View和 | ||
模型对象Model之间的交互。如在Struts中,Action就可以 | ||
作为JSP页面与业务对象之间的中介者。 | ||
|
||
|
||
模式扩展 | ||
-------------------- | ||
中介者模式与迪米特法则 | ||
? 在中介者模式中,通过创造出一个中介者对象,将系 | ||
统中有关的对象所引用的其他对象数目减少到最少, | ||
使得一个对象与其同事之间的相互作用被这个对象与 | ||
中介者对象之间的相互作用所取代。因此,中介者模 | ||
式就是迪米特法则的一个典型应用。 | ||
|
||
中介者模式与GUI开发 | ||
? 中介者模式可以方便地应用于图形界面(GUI)开发中,在 | ||
比较复杂的界面中可能存在多个界面组件之间的交互关系。 | ||
? 对于这些复杂的交互关系,有时候我们可以引入一个中介 | ||
者类,将这些交互的组件作为具体的同事类,将它们之间 | ||
的引用和控制关系交由中介者负责,在一定程度上简化系 | ||
统的交互,这也是中介者模式的常见应用之一。 | ||
|
||
|
||
总结 | ||
-------------------- | ||
中介者模式用一个中介对象来封装一系列的对象交互,中介者使各对 | ||
象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变 | ||
它们之间的交互。中介者模式又称为调停者模式,它是一种对象行为 | ||
型模式。 | ||
? 中介者模式包含四个角色:抽象中介者用于定义一个接口,该接口用 | ||
于与各同事对象之间的通信;具体中介者是抽象中介者的子类,通过 | ||
协调各个同事对象来实现协作行为,了解并维护它的各个同事对象的 | ||
引用;抽象同事类定义各同事的公有方法;具体同事类是抽象同事类 | ||
的子类,每一个同事对象都引用一个中介者对象;每一个同事对象在 | ||
需要和其他同事对象通信时,先与中介者通信,通过中介者来间接完 | ||
成与其他同事类的通信;在具体同事类中实现了在抽象同事类中定义 | ||
的方法。 | ||
|
||
通过引入中介者对象,可以将系统的网状结构变成以中介者为中心的 | ||
星形结构,中介者承担了中转作用和协调作用。中介者类是中介者模 | ||
式的核心,它对整个系统进行控制和协调,简化了对象之间的交互, | ||
还可以对对象间的交互进行进一步的控制。 | ||
? 中介者模式的主要优点在于简化了对象之间的交互,将各同事解耦, | ||
还可以减少子类生成,对于复杂的对象之间的交互,通过引入中介者, | ||
可以简化各同事类的设计和实现;中介者模式主要缺点在于具体中介 | ||
者类中包含了同事之间的交互细节,可能会导致具体中介者类非常复 | ||
杂,使得系统难以维护。 | ||
? 中介者模式适用情况包括:系统中对象之间存在复杂的引用关系,产 | ||
生的相互依赖关系结构混乱且难以理解;一个对象由于引用了其他很 | ||
多对象并且直接和这些对象通信,导致难以复用该对象;想通过一个 | ||
中间类来封装多个类中的行为,而又不想生成太多的子类。 | ||
|
||
|
Oops, something went wrong.