`
renzhelife
  • 浏览: 666628 次
文章分类
社区版块
存档分类
最新评论

行为型设计模式总结

 
阅读更多

行为型设计模式涉及的算法和对象间职责的分配。它不仅描述了对象或类的模式,还描述了它们之间的通信模式。这一点将在本总结中重点分析。那么首先看下各个行为型设计模式的含义。

一、行为型设计模式的含义。

1、观察者模式(ObserverPattern)定义了一种一对多的依赖关系,让多个对象同时关注同一主题。当这个主题对像的状态发生改变时,会通知这些观察者对象,使他们能够自动更新自己

2、命令模式(CommandPattern)将一个请求封装为一个对象,使我们可以用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销操作。

3、模板模式(TempletePattern)定义一个操作中的算法骨架,而将一些步骤延迟到了子类。模板方法可以允许子类在不改变一个算法结构的前提下改变一些具体的步骤。

4、职责链模式(ChainofResponsiblityPattern)是多个对象都有机会处理请求,避免了发送者和接受者之间的耦合。将这些对象连成一条连,并将这个请求沿着这条连传递,直到有对象处理它为止。

5、状态模式(StatePattern)当一个对象状态发生改变时允许改变其行为,这个对象看起来像是改变了其类。

6、备忘录模式(Mementopattern)在不破坏封装性的同时,可以捕获该对象的内部状态,并且在该对象之外可以保存此状态。这样以后就可将该对象恢复到原先的保存状态。

7、策略模式(Strategypattern)定义了算法家族,将这些算法分别封装起来,使他们之间可以相互替代。此模式让算法的替换不会影响到使用的客户。

8、迭代器模式(iteratorpattern)提供一种方法用来顺序的访问聚合对象中各个元素,而又不暴露对象的内部表示。

9、访问者模式(visitorpattern)定义一个作用于某对象内部结构中各个元素的操作。它使我在不改变各个元素的类的前提下定义作用于这些元素的新操作。

10、中介者模式(mediatorpattern)定义一个中介者对象用来封装不同对象间的交互。中介者模式使对象不需要显示的相互引用,从而使其耦合松散,而且可以独立的改变它们之间的交互。

11、解释器模式(interpreterpattern)给定一种语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。

二、实现上的重点

1Observerpattern有两点要注意,一是具体观察观察者(ConcreteObserver)要有具体的主题,其行为会虽具体主题变化而变化;二是主题变化时,要让主题通知所有关心这一主题的观察者更新行为。完成第一个任务则需要在ConcreteObserver中有设置自己关心主题的功能,而如果仅为完成第二个任务则大可在具体的主题(ConcreteSubject)中写入Notify方法,来遍历所有关心此主题的观察者,不过因为每个具体主题都有添加观察者,遍历每个观察者的方法,这样我们应该将其抽象到抽象主题类(Subject)中。

在抽象主题类(Subject)的通知各个观察者更新方法(Notify)中,在遍历每个观察者时会调用观察者的update方法,这时我们注意到,这些观察者行为的名称必须相同,如果不同我们就没办法通知了,而往往它们的方法名是不同的,那我们应该这么办呢?

委托技术对实现上述问题很有帮助。事件委托,允许我们将不同对象的不同方法,同时委托给同一对象的同一事件。这样我们便可以将不同观察者的的不同方法委托给我们的主题类的同一事件了。

这样我们只需在具体主题类中定义可以接受委托的事件,在客户端里将观察者的方法委托给主题类的事件,就可以完成通知的功能了。此时我们还会发现,抽象主题类(subject)也不必知道观察者了,将他们解耦了(不过客户端,稍复杂了点)。实现如下:

具体主题类:

'定义一个委托事件的结构

DelegateSuba()'EventHandler()

PublicEventUpdateAsa'EventHandler

'通知观察者时调用委托事件

PublicSubNotify()ImplementsISubject.Notify

RaiseEventUpdate()

EndSub

客户端

'将两个观察者关心的事情委托给主题对象update事件

AddHandlercsIns.Update,AddressOfObserver1.CloseTV

AddHandlercsIns.Update,AddressOfObserver2.DoExercise

'主题状体发生改变

csIns.SubjectState="老板来了"

'通知观察者变化

csIns.Notify()

2、CommandPattern的意图就是将需要某方法的类与实现某方法的类解耦。这是通过抽象出命令类来做到的,我们可以在需要者类中添加需要的命令来完成它所要的操作。

3、TempletePattern通过模板模式的含义很容清楚我们改变的只是算法的细节,至于算法的结构是不能改变的。重点就是在抽象类(AbstractClass)中定义算法结构和该算法的实现细节。

4、ChainofResponsibilityPattern(职责链模式)就是说一个请求在A类中完成不成,自动由A类交由B类去完成,不行再由B类交由C类完成。解除了请求与每个类耦合。主要实现就是在每个类中要定义添加自己的接替类,即我们能完成后要交由谁去完成的类。

5、StatePattern是说一个类在不同状态下有不同的行为。重点实现是先在不同状态类中实现不同状态下的行为,在行为类中定义设定其状态的方法,这样可以将不同的状态类传入该类中。

6、MementoPattern(备忘录模式)主要是在需要备忘的类(originator)中产生一个Menento类,这个类储存了要备忘的东西,然后将该类存储在一个收集备忘类的类(Caretaker)中。之后Originator可以在Caretaker中得到自己的备忘属性

7、StrategyPattern重点实现就是在需要算法的类(Context)中,如何依据客户的选择,选择算法运算出结果

8、Iteratorpattern(迭代器模式)说白了就是对一个聚合进行遍历。只不过我们现在不是直接调用这个聚合的方法来遍历了,而是同过迭代器(iterator)来遍历,这样就可以将聚合对象的内部表示隐蔽了。

迭代器其实就是提供了一种对聚合中每个元素进行访问的方法。主要完具体迭代器(concreteIterator)中了firstnextisDown等方法,再有就是在具体的聚合(ConcreteAggregate)中利用list的类的一些方法完成对其中数据的访问。

迭代器模式中,由于具体的聚合类(ConreteAggregagte)可以产生具体的迭代器(ConcreteIterator),故而我们对客户端可以隐藏具体的迭代器(concreteIterator),只需定义一个抽象的迭代器来接受具体的聚合(concreteAggregate)产生的具体迭代器。

9、VisitorPattern的目的是将处理与数据结构分开。如果一个系统的数据结构相对稳定,而且又需要易于变化的算法,使用访问者模式就比较合适了。但我们会发现如果数据结构发生变化则是不好改变的。GOF提到此设计模式不常使用,因为系统的数据结构通常是要发生变化的。其重点实现:

(1)在对象结构类(ObjectStructure)中,可以添加和删除元素类,并且能过运行这些元素类的操作。不过每个元素类的操作在不同的Visitor类的条件下有不同的实现

(2)Visitor类不与Element类显示接触,而是通过访问ObjectStructure类来接触,即在objectStructure类中将Visitor类传递给Element类。

(3)每个element类中的方法是调用visitor类中的方法实现的

(4)Visitor类中的方法在不同的Element下表现不同(即在element类中调用Visitor类的方法时也要传入自身element

10、Mediatorpattern要完成的是使不同的对象间的交互不必显示的交互,即Meidator类封装了不同对象间的交互。这一点主要是在对象调用方法传递信息时直接调用mediator类的方法,然后在Mediator类的方法中完成两队象的交互。

11、Interpretorpattern的使用是当有一个语言需要解释执行,并且我可以将这个语言中的句子表示成抽象的语法树时,便可使用解释器模式。

三、比较

1、策略模式(strategypattern)、命令模式(CommandPattern)、职责链模式(ChainofResponsibityPattern)、状态模式(StatePattern)。

四个模式的比较图

看这几个类图,我们发现状态模式和策略模式极为相似。不过状态模式要解决的是一个对象处在不同的状态时会有不同的行为,但状态的判断非常复杂,甚至是每一个状态中又会包含很多的判断(如状态有上午,中午,下午,但这三个状态中每一个状态下又会包括很多判断处于哪个时段的判断)的问题,这时我们用状态模式将复杂的判断转移给了其他几个类判断;而策略模式就是与行为有关,一种策略就仅是一种计算方法。

职责链模式中每个子类也是对应着一定范围的行为,它与策略模式的不同就在于第一个类做不了的事情直接交与下一个类做,而这个过程不必在客户端写代码完成,这几个类是一级一级的关系;策略模式则不会是这样,具体的算法是平级的,只是看客户选择那种算法。

命令模式与上述三个模式在表现形式上有较明显的区别。前三个模式中,需要某行为的类都知道实施此行为的类,而命令模式则将需要某行为的类与实施此行为的类分开了。从意图上,前三个模式都是让需要某行为的类可以选择不同的实施此行为的类;而命令模式则是为了让实施某行为的类可以给不同的需要此行为的类。

2、访问者模式同状态模式的比较

两者看上去都是某个类在不同条件下会有不同的行为表现。每个类的行为并非在自己本身上,而是寄托给了条件类了。不过这个条件在状态模式中用State类表示,在访问者模式中用visitor类表示。

两者的不同点是:

(1)状态模式中这些状态下的行为全部属于一个类,而访问者模式中每个条件下都会有不同类的行为;而且状态模式中的每个具体的状态类中还可能包还对细小状态的判断。

(2)条件与需要此条件的类的接触方式不同,状态模式是将条件直接赋予需要的类,而访问者模式则是通过objectStructure来“访问”;

(3)最重要的应该是两者的目的不同:状态模式是要更好的执行一个类不同状态下的行为,而访问者模式则可以从ObjectStructure类中看出,它是一个结构固定的类,但这个结构下的算法是变化的。

3、访问者模式同模板方法的比较

访问者模式和模板方法都是结构固定,细节可以改变。不过访问者模式固定的是对象结构类(objectStructure)中的元素类,可以改变的是这个对象结构类中的元素类的方法,也就是说组成系统结构的类是不易变化的,但这些类的方法是很容易变化的;同访问者模式不同,模板模式仅是用于一个类的算法细节的改变上。

4、observerpattern和结构型设计模式中的外观模式在功能

我感觉observerpattern和结构型设计模式中的外观模式在功能上有些相似。它们都是由一个类(A)的动作引起另外多个类变化。但为什么一个是行为型设计模式一个却是结构型设计模式呢?一方面是因为那个引发类(A)的身份不同,另一方面则是因为引起多个类变化的原因不同。前者是行为的需要,后则却是结构上的需要。

观察者模式中的类A就是主题类(Subject,外观模式中的类A就是外观类(Facade)。观察者模式中Subject类的是独立的,不是为了什么,为了谁才有的;而外观模式中的facade类却不是独立的,它的出现是带有强烈目的的——为了规划子系统。再有,ObserverPattern引起其他类变化,是因为这些类需要,可以说使这些类给了Subject类通知它们的权利;而Facadepattern中引起其他类变化却是系统的需要,是Facade类强烈要求它们改变的,是系统付给的权利。可以说Facade类并未担任系统的具体工作,而Subject类却担任了。

拿我们的机房收费系统做例子。学生可能会在某一时刻退卡(消除账户),一旦退卡系统就必须要完成一下工作。

1)消除充值记录信息

2)消除上机记录信息

3)计算所剩余额并返还给学生

在这我们依据上面对外观模式和观察者模式的分析,会很清楚的发现这属于观察者模式,而非外观模式。因为这是其他(像消除充值记录、计算余额等)模块(类)的行为需要,而非系统的结构需求;另外退卡本身就是系统的一个任务,是其他模块(类)关注的主题。

四、小做剖析

1、CommandPattern中大话设计模式举的例子的思考

在大话设计模式中有对CommandPattern的优点有这样一句评价:命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分开。我认为其中的第二个“一个”应该改为“这个”。如果是这样的话,前一个对象就应该对应着设计模式中的Invoker,而后一个对象则对应着设计模式中的Receiver。那么大话设计模式中举得烤羊肉的例子就不合适了。

比较

Invoker我感觉应该翻译成:调用者。我们要搞清楚到底谁是调用者命令的类,也就是说是谁要完成某项工作。在买烤羊肉时,这正需要实现烧一串羊肉的人是顾客,而不是服务员,依照命令模式的要领我们要做的是将这正需要完成烧一串羊肉的人与能够实现烧一串羊肉的人分开,也就是说要把顾客和厨师分开。而在此例中服务员和厨师是怎么也分不开的(服务员得通知厨师要做什么)。怎么改善就成了呢,我认为那些命令类就是这个店里服务员持有的菜单

烤羊肉

正如CommandPattern的含义,将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。

1、职责链模式补充状态模式

职责链模式和状态模式

使用状态模式时会使用到职责链模式来配合使用。在StataPatternContext类会根据不同的状态做不同的事情,然而我们不是时时都能清楚context接受的数据处于Context类的何种状态,此时我们就应该使用职责链模式将这些具体状态的职责代替者写明,context类获得的状态如果不属于状态1,则由状态2代理来管理依次类推……

2、备忘录模式

在对一个类的状态(属性)进行保存以便恢复时,为什么不不像prototypepattern实现ICloneable接口的Clone方法。原因之一使用便是利用这个clone方法会将这个类的所有东西全备份,而这有时不是我们全部需要的的;

MementopatternCommandpattern中可撤销操作的完善。在命令模式中支持撤销操作,这一点就应该交给备忘录模式来完成。

这个模式可以对客户端隐藏备份的属性(备忘录类——memento(是不是每个模式都会通过一定手段是客户端与某些类解偶和呢)

五、总结

这些行为型设计模式涉及的是算法和对象间职责的分配。可以说它们解决的是不同方面的大问题,但在多数情况下这些设计模式是相互配合使用的。这些模式中有的是在封装变化上突出、有的是将对象作为参数上突出、有的是对象间通信方式上突出、还有的是对信息发送者和接受者解耦。大致归类如下:

1、封装变化角度

(1)StrategyPattern

(2)StatePattern

(3)MediatorPattern

(4)IteratorPattern

2、对象作为参数

(1)VisitorPattern

(2)MementoPattern

(3)CommandPattern

(4)InterpreterPattern

3、对象间通信方式上

(1)ObserverPattern

(2)MediatorPattern

4、对发送者和接受者解耦

ChainofResponsibilityPattern、命令、观察者、中介者等模式都有所涉及

备注:在此处用英文写的设计模式是第一次出现的位置。

<!--EndFragment-->
分享到:
评论

相关推荐

    c#设计模式 行为型模式 实验报告+源代码

    c#设计模式 行为型模式 包括8个设计模式的实验报告+源代码。实验报告包括实验类图和个人总结的一些小技巧,源代码。包括:职责链模式、命令模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略...

    C#面向对象设计模式纵横谈(22):(行为型模式) State 状态模式

    C#面向对象设计模式纵横谈(22):(行为型模式) State 状态模式

    C#面向对象设计模式纵横谈\18 行为型模式Iterator迭代器模式.zip

    在这里与各位分享本人从网络上下载的C#面向对象设计模式纵横谈系列视频,共有25节,除了第一节需要各位贡献一点资源分以作为对本人上传资源的回馈,后面的其他资源均不需要资源分。敬请期待。 这是第18节:行为型...

    设计模式总结

    设计模式总结,包含创建型模式:5种,结构型模式:7种,行为型模式:12种

    23种设计模式经典案例(C++版)

    设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代 码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的;设计...

    行为型模式+结构型模式+创建型模式:三大设计模式实例剖析与深入解读

    行为型模式+结构型模式+创建型模式:三大设计模式实例剖析与深入解读 行为型模式 备忘录模式 +结构型模式 创建型模式总结 +创建型模式

    设计模式自己总结一句话描述

    设计模式分为三大类: 创建型模式,共五种: 工厂方法模式、抽象工厂模式、单例模式、构建者模式、原型模式。 结构型模式,共七种: 适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。...

    灸哥讲行为型设计模式以及实战演练多种设计模式

    灸哥用自己的总结方式讲解创建型设计模式,让你对设计模式的掌握更加清晰 1、什么是 X 设计模式? 2、为什么要用 X 设计模式? 3、如何使用 X 设计模式? 4、是否存在缺陷和不足? 5、如何缓解缺陷和不足? 同时本篇...

    C#面向对象设计模式纵横谈(视频与源码)

    讲 师:李建忠 上海祝成信息科技有限公司 高级培训讲师 MSDN特邀讲师 C#面向对象设计模式纵横谈(1):面向对象设计模式与原则 C#面向对象设计模式纵横谈(2):... C#面向对象设计模式纵横谈(25):设计模式总结

    ASP.NET 设计模式(word型)ASP.NET 设计模式(word型)

    ASP.NET 设计模式 程序的设计最终还是归于算法和设计模式,24种设计模式,会让你的开发层次提升一个大的空间。 创建型模式, 结构型模式 行为型模式 面向对象设计模式原则 设计模式总结

    lua设计模式总结

    行为模式 1、策略模式lua实现 2、模板方法模式lua实现 3、观察者模式lua实现 4、状态模式lua实现 5、迭代器模式lua实现 6、备忘录模式lua实现 7、命令模式lua实现 8、职责链模式lua实现 9、解释器模式lua实现 10、...

    设计模式笔记(包含所有设计模式)个人总结提炼笔记

    设计模式是一种解决软件设计问题的经验总结,是在软件开发过程中经过反复验证的最佳实践。设计模式提供了一套通用的解决方案,可以帮助开发人员更好地组织和设计代码,提高代码的可读性、可维护性和可扩展性。 设计...

    设计模式--C++

    1.1 什么是设计模式 2 1.2 Smalltalk MVC 中的设计模式 3 1.3 描述设计模式 4 1.4 设计模式的编目 5 1.5 组织编目 7 1.6 设计模式怎样解决设计问题 8 1.6.1 寻找合适的对象 8 1.6.2 决定对象的粒度 9 1.6.3 指定对象...

    设计模式可复用面向对象软件的基础.zip

    本书设计实例从面向对象的设计中精选出23个设计模式,总结了面向对象设计中最有价值的经验,并且用简洁可复用的形式表达出来。本书分类描述了一组设计良好,表达清楚的软件设计模式,这些模式在实用环境下有特别有用...

    所有设计模式总结

    上面总结用的是思维导图,(注意:需要用xmind软件打开)设计模式总结,分为三个大类型:创建型,结构型,行为型。总结了它们适用于解决什么问题,用了后所要达到的意图。

    设计模式(.PDF)

    1.1 什么是设计模式 2 1.2 Smalltalk MVC中的设计模式 3 1.3 描述设计模式 4 1.4 设计模式的编目 5 1.5 组织编目 7 1.6 设计模式怎样解决设计问题 8 1.6.1 寻找合适的对象 8 1.6.2 决定对象的粒度 9 1.6.3 指定对象...

    23种设计模式,创建型模式共5种,结构型模式7种,行为型模式11种

    设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的 总结。 使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于...

    GOLF设计模式(C++语言版)

    1.1 什么是设计模式 2 1.2 Smalltalk MVC中的设计模式 3 1.3 描述设计模式 4 1.4 设计模式的编目 5 1.5 组织编目 7 1.6 设计模式怎样解决设计问题 8 1.6.1 寻找合适的对象 8 1.6.2 决定对象的粒度 9 1.6.3 ...

    《国外写的,翻译版本》设计模式

    最出名的设计模式,语言诙谐明了。 目 录 序言 前言 读者指南 第1章 引言 1 1.1 什么是设计模式 2 1.2 Smalltalk MVC中的设计模式 3 1.3 描述设计模式 4 1.4 设计模式的编目 5 1.5 组织编目 7 1.6 设计模式怎样解决...

Global site tag (gtag.js) - Google Analytics