哈哈,大家新年快乐。本来说要尽快把这个话题结束的,结果因为考试,我的Open source的project而拖到了现在。今天和明天尽可能的结束它们吧~谢谢大家的支持,也对我的拖延表示歉意。。。
与前两种模式不同,一些行为型模式需要在动态过程中才能被良好的表达,这也给这些模式的理解加深了难度。特别是在对已有系统进行逆向分析的时候,对于一些混合使用了多个设计模式的组件而言,想准确的弄清楚用了哪些模式,更是困难。所以对设计模式使用动机的理解,是很重要的。
这个是题外话。
首先来讨论一下Chain of responsibility
。
对于职责链来说,“链”这个词是关键。
它的一个隐含的意义就是,消息的散播有序的。这种序列可以表现为主从关系,或先后关系。
在运行时,消息的传播完全有可能是树状或者呈现DAG这样的结构(例如在composite中)。它适合于消息传播层次化的时候,如果不同对象之间的消息沟通是呈现复杂的网状或者扁平状,那么消息链就完全没有作用了。
如果消息的传递可以是无序的,或者不同消息接受者之间没有明显的主从关系,那么更适合用一些更加灵活的手法,比如signal-slot idioms。不过,signal slot与COR的关注点并不同,前者比后者要更加关注与实现细节和消息通讯的局部情况。
COR和Decorator也有一些相似之处的,只不过COR的关系是在动态过程中体现,而Decorator是在静态过程中体现;并且COR只是强调信息的转发,而Decorator则是强调功能的增强。前者强调模式的协作组件间提供一个机制,以及怎样实现这个机制;后者则强调模式的协作组件之间需要什么样的功能逻辑。
Command是个非常强大的工具,它的强大与难以理解对很多初学者来说都是很可怕的事情。
但是对于Command的基本理解,只需要知道它是C++版的Callback,就足够了。同时,对于Command的使用,我认为也仅限于Callback,如果Command的职责超出了Callback之外的用途,是需要谨慎对待的。Command解决了消息内容与组件之间的耦合问题,但是,它并没有解决交互耦合的问题。
以UI设计为例,使用Command可以将UI元素与逻辑之间互相不知道对方的内容。但是,在仅仅有Commmad的情况下,逻辑必须知道“UI”的基本情况才能正确运行(比方说与UI一起工作,Command需要绑定哪些要素)。实际上我们对它的期望是,逻辑部分不知道UI的存在,无论是Command Line下(此Command非彼Command,哈哈)还是GUI下,甚至作为一个系统的子系统出现,它都能正常的工作。而为与UI协同工作的Command很有可能就具备了UI下的Command实现所特有的特征。这些特征在移植到其它环境下会有一些困难,并需要做出设计上的再度取舍,Command模式本身也成为了一个包袱。
其次,Command模式通常用于多对多的关系中,这使得Command在时间上和逻辑上不连贯,也会给系统理解带来一定的难度。因此,如果将Command与Mediator或者COR、或者Visitor这样的模式搭配使用,将Command理解为实践技术与惯用手法,而将Mediator等作为设计元素来考虑的话,可能更加恰当一些。Command提供了消息的解耦合,而其它的模式则连同通信耦合也一并解除了。
Interpretor恐怕是DP里面所讨论的用途最窄的模式了。
实际上,稍微有点经验的人,对这个模式都不陌生。Composite,Interpretor和Builder之间有着千丝万缕的联系。前者体现了结构上的层次,Builder则适合于构造Composite,而Interpretor,可以作为Builder用于构造Composite的信息源。从更加宽泛的概念讲,Interpretor适合于将一种层次化的信息转换成另外一种表达方式。最典型的例子就是带有子结构的类的I/O实现,例如将对象持久化为XML或者逆持久化,在这里面就少不了它的身影。