1、设计模式,Design Patterns,设计模式编目(Catalog),2,Observer(观察者)模式的描述,3,模式名和分类(Name),模式名:Observer(观察者) 分类:对象行为型模式,4,意图(Intent),定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。,5,别名(Also Known As),依赖(Dependents) 发布-订阅(Publish-Subscribe),6,动机(Motivation),将一个系统分割成一系列相互协作的类有一个常见的副作用: 需要维护相关对象间的一致性 我们不希望为了维持一致性而使各类紧密耦合,因为这样降低了它们的可重用性。,7,动机(Motivation),8,L2,Observer,动机(Motivation),一个表格对象和一个柱状图对象可使用不同的表示形式描述同一个应用数据对象的信息。 表格对象和柱状图对象互相并不知道对方的存在,这样使你可以根据需要单独复用表格或柱状图。 但在这里是它们表现的似乎互相知道。当用户改变表格中的信息时,柱状图能立即反映这一变化,反过
2、来也是如此。 Observer模式描述了如何建立这种关系。这一模式中的关键对象是目标(subject)和观察者(observer)。,9,适用性(Applicability),以下情形适用Observer(观察者)模式: 当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。 当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之, 你不希望这些对象是紧密耦合的。,10,结构(Structure),11,参与者(Participants),Subject(目标) 目标知道它的观察者。可以有多个观察者观察同一个目标。 提供注册和删除观察者对象的接口。 Observer(观察者) 为那些在目标发生改变时需通知的对象定义一个更新接口。 ConcreteSubject(具体目标) 将有关状态存入各ConcreteObserver对象。 当它的状态发生改变时,向它的各个观察者发出通知。,12,参与者(Participants),ConcreteObse
3、rver(具体观察者) 维护一个指向ConcreteSubject对象的引用。 存储有关状态,这些状态应与目标的状态保持一致。 实现Observer的更新接口以使自身状态与目标的状态保持一致。,13,协作(Collaborations),当ConcreteSubject发生任何可能导致其观察者与其本身状态不一致的改变时,它将通知它的各个观察者。 在得到一个具体目标的改变通知后,ConcreteObserver对象可向目标对象查询信息。ConcreteObserver使用这些信息以使它的状态与目标对象的状态一致。,14,协作(Collaborations),15,效果(Consequences),Observer模式允许你独立的改变目标和观察者。你可以单独复用目标对象而无需同时复用其观察者,反之亦然。它也使你可以在不改动目标和其他的观察者的前提下增加观察者。 优缺点: 目标和观察者间的抽象耦合 一个目标所知道的仅仅是它有一系列观察者,每个都符合抽象的Observer类的简单接口。 支持广播通信 意外的更新(缺点) 因为一个观察者并不知道其它观察者的存在,它可能对改变目标的最终代价一无所知
4、。,16,Template Method(模板方法) 模式的描述,17,模式名和分类(Name),模式名:Template Method(模板方法) 分类:类行为型模式,18,意图(Intent),定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。,19,动机(Motivation),考虑一个提供Application和Document类的应用框架。 Application类负责打开一个已有的以外部形式存储的文档,如一个文件。一旦一个文档中的信息从该文件中读出后,它就由一个Document对象表示。,20,动机(Motivation),用框架构建的应用可以通过继承Application和Document来满足特定的需求。 例如,一个绘图应用定义DrawApplication和DrawDocument子类;一个电子表格应用定义SpreadsheetApplication和SpreadsheetDocument子类,21,L2,动机(Motivation),抽象的Application类在它的
5、OpenDocument操作中定义了打开和读取一个文档的算法。OpenDocument定义了打开一个文档的每一个主要步骤。它检查该文档是否能被打开,创建与应用相关的Document对象,将它加到它入的文档集合中,并且从一个文件中读取该Document。,22,void Application:OpenDocument (const char* name) if (!CanOpenDocument(name) / cannot handle this document return; Document* doc = DoCreateDocument(); if (doc) _docs-AddDocument(doc); AboutToOpenDocument(doc); doc-Open(); doc-DoRead(); ,动机(Motivation),我们称OpenDocument为一个模板方法(Template Method) 一个模板方法用一些抽象的操作定义一个算法,而子类将重定义这些操作以提供具体的行为。 Application的子类将定义检查一个文档是否能够被打开(CanOpe
6、nDocument)和创建文档(DoCreateDocument)的具体算法步骤。 Document子类将定义读取文档(DoRead)的算法步骤 通过使用抽象操作定义一个算法中的一些步骤,模板方法确定了它们的先后顺序,但它允许Application和Document子类改变这些具体步骤以满足它们各自的需求。,23,适用性(Applicability),以下情形适用Template Method模式: 一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。 控制子类扩展,24,结构(Structure),25,参与者(Participants),AbstractClass(抽象类,如Application) 定义抽象的原语操作(primitive operation),具体的子类将重定义它们以实现一个算法。 实现一个模板方法,定义一个算法的骨架。该模板方法不仅调用原语操作,也调用定义在AbstractClass或其他对象中的操作。 ConcreteClass(具体类,如MyApplication) 实现原语操作
7、以完成算法中与特定子类相关的步骤。,26,协作(Collaborations),ConcreteClass靠AbstractClass来实现算法中不变的步骤。,27,效果(Consequences),模板方法是一种代码复用的基本技术。它们在类库中尤为重要,它们提取了类库中的公共行为。 模板方法调用下列类型的操作: 具体的操作(ConcreteClass或对客户类的操作)。 具体的AbstractClass的操作(即,通常对子类有用的操作)。 原语操作(即,抽象操作)。 Factory Method 钩子操作(hook operations),它提供了缺省的行为,子类可以在必要时进行扩展。,28,相关模式(Related Patterns),Factory Method模式常被模板方法调用。 在动机的例子中,DoCreateDocument就是一个Factory Method,它由模板方法OpenDocument调用。 Strategy:模板方法使用继承来改变算法的一部分。Strategy使用委托来改变整个算法。,29,实现代码分析,30,Observer模式的实现代码分析,作用: 定义
8、对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。,31,Observer模式的实现代码分析,解析: Observer模式定义的是一种一对多的关系,这里的“一”就是图中的Subject类,而“多”则是Observer类。 当Subject类的状态发生变化的时候通知与之对应的所有Observer类,让它们也相应地更新各自的状态。 支持动态地添加和删除Observer对象的功能。 Observer模式的实现要点: 一般subject类都是采用链表等容器来存放Observer对象 抽取出Observer对象的一些公共的属性形成Observer基类,而Subject中保存的则是Observer类对象的指针,这样就使Subject和具体的Observer实现了解耦,也就是Subject不需要去关心到底是哪个Observer对象放进了自己的容器中。,32,Observer模式的实现代码分析,代码 Observer.h Observer.cpp Main.cpp,33,运行结果: Attach an Observer Attach an Observ
9、er SetState By ConcreateSubject Notify Observerss State GetState By ConcreateSubject The ObeserverState is 4 GetState By ConcreateSubject The ObeserverState is 4 Detach an Observer SetState By ConcreateSubject Notify Observerss State GetState By ConcreateSubject The ObeserverState is 10 请按任意键继续. . .,Template Method模式的实现代码分析,作用: 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。,34,Template Method模式的实现代码分析,抽象基类: AbstractClass:抽象基类,定义算法的轮廓。 解析: Template Method 的关键在于在基类中定义了一个算法的轮廓,而算法每一步具体的实现留给了派生类。 这样也会造成设计的灵活性不高的缺点,因为轮廓已经定下来了要想改变就比较难了。,35,Template Method模式的实现代码分析,代码 TemplateMethod.h TemplateMethod.cpp Main.cpp,36,运行结果: PrimitiveOperation1 by ConcreateClass PrimitiveOperation2 by ConcreateClass 请按任意键继续. . .,已学模式回顾,37,设计模式编目(Catalog),38,创建型模式,Factory Method Abstract Factory,39,Factory Method(工厂方法),定义一个用于创建对象的接口,让子类决定实例化哪一个类。 使一个类的实例化延迟到其子类。,40,Factory Method(工厂方法),抽象基类: Product:创建出来的对象的抽象基类 Creator:创建对象的工厂方法的抽象基类 接口函数: Creator:FactoryMetho
《软件设计-理论课05》由会员luoxia****01805分享,可在线阅读,更多相关《软件设计-理论课05》请在金锄头文库上搜索。