12、面向对象程序设计

第十二章 面向对象程序设计

根据考试大纲,本章要求考生掌握以下几个方面的知识点。
(1)分析模式与设计模式知识
(2)面向对象程序设计知识
(3)用C++语言实现常见的设计模式及应用程序。
(4)用Java语言实现常见的设计模式及应用程序。
从历年的考试情况来看,本章的考点主要集中于:设计模式基本概念、设计模式的分类、设计模式的特点与应用场合以及面向对象程序语言与设计模式思想的综合案例。

1.什么是设计模式

设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式可以提高代码复用度、让代码更容易被他人理解、保证代码可靠性。毫无疑问,设计模式于己、于他人、于系统都是有利的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。
在这里插入图片描述

在这里插入图片描述

2.设计模式的组成

一般来说,一个模式有4个基本成分,分别是模式名称、问题、解决方案和效果。

(1)模式名称

每个模式都有一个名字,帮助我们讨论模式和它所给出的信息。模式名称通常用来描述一个设计问题、它的解法和效果,由一到两个词组成。模式名称的产生使我们可以在更高的抽象层次上进行设计并交流设计思想。

(2)问题

问题告诉我们什么时候要使用设计模式、解释问题及其背景。例如,MVC(Model-ViewControler,模型-视图-控制器)模式关心用户界面经常变化的问题。它可能描述诸如如何将一个算法表示成一个对象这样的特殊设计问题。在应用这个模式之前,也许还要给出一些该模式的适用条件。

(3)解决方案

解决方案描述设计的基本要素,它们的关系、各自的任务以及相互之间的合作。解决方案并不是针对某一个特殊问题而给出的。设计模式提供有关设计问题的一个抽象描述以及如何安排这些基本要素以解决问题。—个模式就像一个可以在许多不同环境下使用的模板,抽象的描述使我们可以把该模式应用于解决许多不同的问题。
模式的解决方案部分给出了如何解决再现问题,或者更恰当地说是如何平衡与之相关的强制条件。在软件体系结构中,这样的解决方案包括两个方面。
第一,每个模式规定了一个特定的结构,即元素的一个空间配置。例如,MVC模式的描述包括以下语句:“把一个交互应用程序划分成三部分,分别是处理、输入和输出”。
第二,每个模式规定了运行期间的行为。例如,MVC模式的解决方案部分包括以下陈述:“控制器接收输入,而输入往往是鼠标移动、点击鼠标按键或键盘输入等事件。事件转换成服务请求,这些请求再发送给模型或视图”。

(4)效果

效果描述应用设计模式后的结果和权衡。比较与其他设计方法的异同,得到应用设计模式的代价和优点。对于软件设计来说,通常要考虑的是空间和时间的权衡。也会涉及到语言问题和实现问题。对于一个面向对象的设计而言,可重用性很重要,效果还包括对系统灵活性、可扩充性及可移植性的影响。明确看出这些效果有助于理解和评价设计模式。

3. 设计模式的分类

在这里插入图片描述

在设计模式概念提出以后,很多人把自己的一些成功设计规范成了设计模式,一时间提出了许许多多的模式,但这些模式并没有都为众人所接受,成为通用的模式。直到ErichGamma在他的博士论文中总结了一系列的设计模式,做出了开创性的工作。他用一种类似分类目录的形式将设计模式记载下来。我们称这些设计模式为设计模式目录。根据模式的目标(所做的事情),可以将它们分成创建性模式(creational)、结构性模式(structural)和行为性模式(behavioral)。创建性模式处理的是对象的创建过程,结构性模式处理的是对象/类的组合,行为性模式处理类和对象间的交互方式和任务分布。根据它们主要的应用对象,又可以分为主要应用于类的和主要应用于对象的。
表15-1是ErichGamma等人总结的23种设计模式,这些设计模式通常被称为GoF(Gang of Four,四人帮)模式。因为这些模式是在《Design Patterns: Elements of Reusable ObjectOriented Software》中正式提出的,而该书的作者是Erich Gamma、Richard Helm、RalphJohnson 和 John Vlissides,这几位作者常被称为“四人帮”。
在这里插入图片描述
其中带*为关于类的,其他是关于对象的。在后面的章节中,我们将详细论述23种模式的特点、应用场合及UML图。
在这里插入图片描述

习题

试题1
在面向对象软件开发过程中,采用设计模式__(1)__。
(1)A.以复用成功的设计
B.以保证程序的运行速度达到最优值
C.以减少设计过程创建的类的个数
D.允许在非面向对象程序设计语言中使用面向对象的概念

试题2
设计模式根据目的进行分类,可以分为创建型、结构型和行为型三种。其中结构型模式用于处
理类和对象的组合。__(2)__模式是一种结构型模式。
(2)A.适配器(Adapter)B.命令(Command)
C.生成器(Builder)D.状态(State)

试题3
在进行面向对象设计时,采用设计模式能够__(3)__。
(3)A.复用相似问题的相同解决方案 B.改善代码的平台可移植性
C.改善代码的可理解性 D.增强软件的易安装性

试题4
设计模式具有__(4)__的优点。
(3)A.适应需求变化 B.程序易于理解
C.减少开发过程中的代码开发工作量 D.简化软件系统的设计

答案
试题1分析
模式是一种问题的解决思路,它已经适用于一个实践环境,并且可以适用于其它环境。设计模
式通常是对于某一类软件设计问题的可重用的解决方案,将设计模式引入软件设计和开发过程,其
目的就在于要重用成功的软件开发经验。
试题1答案
(1)A
试题2分析
本题考查设计模式的分类,相关分类情况请参看表15-1。
试题2答案
(2)A
试题3分析
设计模式是一种指导,在一个良好的指导下,有助于完成任务,有助于作出一个优良的设计方
案,达到事半功倍的效果,而且会得到解决问题的最佳办法。采用设计模式能够复用相似问题的相
同解决方案,加快设计的速度,提高了一致性。
试题3答案
(3)A
试题4分析
设计模式是用一种固定的解决方案来解决某一类问题,这种方式第一大优点是方案出错的可能
性很小,因为这些方案都是经过很多人实践总结出来的;第二是适应需求变化,
试题4答案
(4)A


在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

1. 简单工厂模式

简单工厂(Simple Factory)专门定义一个类的实例,被创建的实例通常都具有共同的父类。

简单工厂模式又称为静态工厂方法(Static Factory Method)模式,属于创建型模式,通常它根据自变量的不同返回不同类的实例。

简单工厂模式的实质是由一个工厂类根据传入的参量,动态决定应该创建出哪一个产品类的实例。简单工厂模式实际上不属于GoF的23个模式,但它可以作为GoF的工厂方法模式(Factory Method)的一个引导。其UML类模型如图15-1所示,其涉及的参与者有三个:工厂角色、抽象产品角色和具体产品角色。
在这里插入图片描述
工厂(Creator)角色:是简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。
抽象产品(Product)角色:是简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
具体产品(Concrete Product)角色:是简单工厂模式的创建目标,所创建的对象都是充当这个角色的某个具体类的实例。

2. 工厂方法模式

工厂模式(Factory)又称为工厂方法模式,也叫虚拟构造函数(Virtual Constructor)模式或者多态工厂模式。在工厂模式中,父类负责定义创建对象的公共接口,而子类则负责生成具体的对象,这样做的目的是将类的实例化操作延迟到子类中完成,即由子类来决定究竟应该实例化哪一个类。

在简单工厂模式中,一个工厂类处于对产品类进行实例化的中心位置,它知道每个产品类的细节,并决定何时哪一个产品类应当被实例化。简单工厂模式的优点是能够使客户端独立于产品的创建过程,并且在系统中引入新产品时无须对客户端进行修改,缺点是当有新产品要加入到系统中时,必须修改工厂类,以加入必要的处理逻辑。简单工厂模式的致命弱点就是处于核心地位的工厂类,因为一旦它无法确定要对哪个类进行实例化,就无法使用该模式,而工厂方法模式则可以很好地解决这一问题。工厂方法模式的UML类图的如图15-2所示。

其中的类或对象之间的关系为:
产品(Product)角色:定义产品的接口。
真实产品(ConcreteProduct)角色:实现接口Product的类。
工厂(Creator)角色:声明工厂方法(FactoryMethod),返回一个产品。
真实工厂(ConcreteCreator)角色:实现工厂方法(FactoryMethod),则客户调用,返回一个产品的实例。
在这里插入图片描述

3. 抽象工厂

抽象工厂提供了一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂(Abstract Factory)模式又称为Kit模式,属于对象创建型模式。
抽象工厂模式与工厂模式最大的区别在于:工厂模式针对的是一个产品的等级结构,而抽象工厂模式则针对的是多个产品等级结构。正因为如此,在抽象工厂模式中经常会用到产品族这一概念,它指的是位于不同的产品等级结构中,并且功能相互关联的产品系列。其UML类模型如图15-3所示。其中的类或对象之间的关系为:
抽象工厂(AbstractFactory):声明生成抽象产品的方法。
具体工厂(ConcreteFactory):执行生成抽象产品的方法,生成一具体的产品。
在这里插入图片描述

4. 单例模式

单例(Singleton)模式确保其一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类,它提供全局访问的方法。单例模式的要点有三个:一是某个类只能有一个实例;二是它必须自选创建这个实例;三是它必须自行向整个系统提供这个实例。UML类模型15-4所示。
在这里插入图片描述
类和对象之间的关系为:
单例(Singleton):提供一个instance方法,让客户可以使用它的唯一实例。内部实现只生成一个实例。

5. 构建模式

构建(Builder)模式将把一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。构建模式是一步步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不知道内部的具体构建细节。UML类模型如图8-7所示。其中的类或对象之间的关系为:
抽象构建者(Builder):为创建一个Product对象的各个部件指定抽象接口。
具体构建者(ConcreteBuilder):实现Builder接口,构造和装配产品的各个部件;定义并明确它所创建的表示;提供一个返回这个产品的接口。
指挥者(Director):构建一个使用Builder接口的对象。
产品(Product):被构建的复杂对象,具体构建者创建该产品的内部表示并定义它的装配过程;包含定义组成部件的类,包括将这些部件装配成最终产品的接口。

在这里插入图片描述

6. 原型模式

原型(Prototype)模式指定创建对象的种类,并且通过复制这些原型创建新的对象。原形模式允许一个对象再创建另一个可定制的对象,根本无须知道任何创建的细节。工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象复制自己来实施创建过程。UML类模型如图15-6所示。
在这里插入图片描述
其中类和对象之间的关系为:
**抽象原型(Prototype)类:**定义具有克隆自己的方法的接口。
具体原型(ConcretePrototype)类:实现具体的克隆方法。
客户(Client)类:通过克隆生成一个新的对象。

7. 适配器模式

适配器(Adapter)模式将一个接口转换成为客户想要的另一个接口,适配器模式使接口不兼容的那些类可以一起工作。其UML类模型如图15-7所示。
其中类的定义及其关系如下:
目标抽象(Target)类:定义客户要用的特定领域的接口。
适配器公接口(Adapter):调用另一个接口,作为一个转换器。
适配器母接口(Adaptee):Adapter需要接入。
客户调用(Client)类:协同对象符合Adapter适配器(公接口)。
在这里插入图片描述

8. 合成模式

合成(Composite)模式组合多个对象形成树型结构以表示整体—部分的结构层次。合成模式对单个对象和合成对象的使用具有一致性。其UML类模型如图15-8所示。
在这里插入图片描述
其中类和对象的关系如下:
部件抽象接口(Component):为合成的对象声明接口;某些情况下,实现从此接口派生出所有类共有的默认行为;定义一个接口可以访问及管理它的多个部分(GetChild);如果必要也可以在递归结构中定义一个接口访问它的父节点,并且实现它。
叶子部件(Leaf):在合成中表示叶节点对象,叶节点没有子节点;定义合成中原接口对象的行为。
合成(Composite)类:定义有子节点(子部件)的部件的行为;存储子节点(子部件);在Component接口中实现与子部件相关的操作。
客户(Client)应用程序:通过Component接口控制组合部分的对象。

9. 装饰模式

装饰(Decorator)模式动态地给一个对象增加其他职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活。UML类模型如图15-9所示。
在这里插入图片描述
其中类和对象的关系为:
部件(Component):定义对象的接口,可以给这些对象动态增加职责(方法)。
具体部件(Concrete Component):定义具体的对象,Decorator可以给它增加额外的职责(方法)。
装饰抽象(Decorator)类:维护一个内有的Component,并且定义一个与Component接口一致的接口。
具体装饰对象(ConcreteDecorator):为内在的具体部件对象增加具体的职责(方法)。

10. 代理模式

代理(Proxy)模式为其他对象提供一个代理或地方以控制对这个对象的访问。当客户向代理对象第一次提出请求时,将实例化为真实的对象,并且将请求传给它,以后所有的客户请求都经由proxy传给封装了的真实对象。其UML类模型如图15-10所示。
在这里插入图片描述
其中的类和对象的关系为:
代理(Proxy):维护一个引用使得代理可以访问实体,如果RealSubject和Subject的接口相同,Proxy会引用Subject;提供一个与Subject的接口相同的接口,使得代理可以用来替代实体,这与适配器模式类似;控制对实体的访问并且负责创建及删除它。
抽象实体(Subject)接口:为RealSubject实体及Proxy代理定义相同的接口中,使得RealSubject在任何地方都可以使用Proxy来访问。
实体(RealSubject):定义Proxy代理的实体。

11. 享元模式

享元(Flyweight)模式运用共享技术有效地支持大量细粒度的对象。系统只使用少量的对象,而这些对象都相近、状态变化很小、对象使用次数较多。其UML类模型如图15-11所示。
在这里插入图片描述
其中类和对象的关系为:
享元(Flyweight)类:声明一个接口,通过它可以接收外来的参数(状态),并对新状态做出处理(作用)。
具体享元(ConcreteFlyweight)类:实现Flyweight的接口,并为内部增加存储空间。
ConcreteFlyweight对象必须是可以共享的,它所存储的状态必须是内部的,即它独立存在于自己的环境中。
不共享的具体享元(UnsharedConcreteFlyweight)类:不是所有的Flyweight子类都需要被共享,Flyweight的共享不是强制的。在某些Flyweight的结构层次中,UnsharedConcreteFlyweight对象通常将ConcreteFlyweight对象作为子节点。
享元类工厂(FlyweightFactory):创建并管理flyweight对象;确保享用flyweight,当用户请求一个flyweight对象时,FlyweightFactory提供一个已创建的实例或者创建一个实例(如果不存在)。
客户应用程序(Client):维持一个对flyweight的引用;计算或存储一个或多个flyweight的外部状态。

12. 门面模式

门面(Facade)模式也称为外观模式,提供一个统一的接口去访问多个子系统的多个不同的接口。门面模式定义了一个高层次的接口,使得子系统更容易被使用。其UML类模型如图15-12所示。
在这里插入图片描述
其中类和对象的关系为:
门面(Facade)类:知道哪些子系统负责处理哪些请求;将客户的请求传递给相应的子系统对象处理。
子系统(Subsystem)类:实现子系统的功能;处理由Facade传过来的任务;子系统不用知道Facade,在任何地方都没有引用Facade。

13. 桥接模式

桥接(Bridge)模式将抽象部分与实现部分分离,使得它们两部分可以独立地变化。其UML类模型如图15-13所示。其中类和对象的关系为:
在这里插入图片描述
抽象(Abstraction)类:定义抽象类的接口,维护一个实现抽象(Implementor)的对象。
扩充抽象(RefinedAbstraction)类:扩充由Abstraction定义的接口。
实现(Implementor)类接口:定义实现类的接口,这个接口不一定要与Abstraction的接口完全一致,事实上这两个接口可以完全不同,一般地讲Implementor接口仅提供基本操作,而Abstraction定义的接口可能会做更多更复杂的操作。
具体实现(ConcreteImplementor)类:具体实现Implementor的接口。

14. 策略模式

策略(Strategy)模式定义一系列的算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化。其UML类模型如图15-14所示。
在这里插入图片描述

其中类和对象的关系为:
抽象策略(Strategy)类:定义一个公共的接口给所有支持的算法,Context使用这个接口调用ConcreteStrategy定义的算法。
具体策略(ConcreteStrategy)类:调用Strategy接口实现具体的算法。
上下文(Context):用ConcreteStrategy对象配置其执行环境;维护一个对Strategy的引用实例;可以定义一个接口供Strategy存取其数据。

15. 模板方法模式

模板方法(Template Method)模式定义一个操作中算法的骨架,以将一些步骤延缓到子类中实现。模板方法让子类重新定义一个算法的某些步骤而无须改变算法的结构。其UML类模型如图15-15所示。
在这里插入图片描述

其中类和对象的关系为:
抽象(AbstractClass)类:定义一个抽象原始的操作,其子类可以重定义实现算法的各个步骤;实现一个模板方法定义一个算法的骨架,此模板方法不仅可以调用原始的操作,还可以调用定义于AbstractClass中的方法或其他对象中的方法。
具体(ConcreteClass)类:实现原始的操作以完成子类特定算法的步骤。

16. 迭代器模式

迭代器(Iterator)模式提供一种方法可以访问聚合对象,而不用暴露这个对象的内部表示。其UML类模型如图15-16所示。
在这里插入图片描述

其中类和对象的关系为:
迭代器(Iterator):定义访问和遍历元素的接口。
具体迭代器(ConcreteIterator):实现迭代器的接口;在遍历时跟踪当前聚合对象中的位置。
聚合(Aggregate):定义一个创建迭代器对象的接口。
具体聚合(ConcreteAggregate):创建迭代器对象,返回一个具体迭代器实例。

17. 责任链模式

责任链(Chain of Responsibility)模式能避免请求发送者与接收者耦合在一起,让多个对象都有可能接收接求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理为止。该模式的UML类模型如图15-17所示。
在这里插入图片描述
其中类和对象的关系:
传递者(Handler)接口:定义一个处理请求的接口;或实现链中下一个对象。
具体传递者(ConcreteHandler):处理它所负责的请求;可以访问链中下一个对象;如果可以处理请求,就处理,否则将请求转发给后继者。
客户应用程序(Client):向链中的对象提出最初的请求。

18. 命令模式

命令(Command)模式将一个请求封装成一个对象,因此可以参数化多个客户的不同请求,将请求排队,记录请求日志,并且支持撤销操作。其UML类模型如图15-18所示。
在这里插入图片描述
其中类和对象之间的关系为:
抽象命令(Command)类:声明执行操作的一个接口。
具体命令(ConcreteCommand)类:将一个接收者对象绑定于一个动作;实现Execute方法,以调用接收者的相关操作(Action)。
客户应用程序(Client):创建一个具体命令类的对象,并且设定它的接收者。
调用者(Invoker):要求一个命令对象执行一个请求。
接收者(Receiver):知识如何执行关联请求的相关操作。

19. 备忘录模式

备忘录(Memento)模式在不破坏封装的前提下,捕获并且保存一个对象的内部状态,这样可以将对象恢复到原先保存的状态。其UML类模型如图15-19所示。
在这里插入图片描述
其中类和对象的关系为:
备忘录(Memento):保持Originator(原发器)的内部状态,根据原发器来决定保存哪些内部的状态;保护原发器之处的对象访问备忘录,备忘录可以有效地利用两个接口,看管者只能调用狭窄(功能有限)的接口,即只能传递备忘录给其他对象,而原发器可以调用一个宽阔(功能强大)的接口,通过这个接口可以访问所有需要的数据,使原发器可以返回先前的状态。理想的情况是,只允许生成本备忘录的那个原发器访问本备忘录的内部状态。
原发器(Originator):创建一个备忘录,记录它的当前内部状态;可以利用一个备忘录来恢复它的内部状态。
看管者(Caretaker):只负责看管备忘录;不可以对备忘录的内容操作或检查。
在这里插入图片描述

Memento模式经常在很多应用软件出现,按Ctrl-Z会取消最后一次用户操作。如果不用Memento模式,Caretaker对象要备份Originator对象的状态,Originator就要具有所有需要访问成员的方法,当要恢复Originator对象的状态时,Caretaker更要清楚Originator内部的结构。这种
严紧的凝结的结果是,发生在Originator上的任何修改,Caretaker都要作出相应的修改,这样就打破了对象封装的特点。图15-20是没有采用Memento模式时的结构。
而Memento模式是解决这种问题的最好办法,Memento类成了Originator及Caretaker的媒介,封装保存Originator的备份状态,当Originator被提出备份请求时,它就会创建一个Memento对象返回给Caretaker。Caretaker不可以看到Memento对象的内部信息,需要时Caretaker可以返回备份的Memento对象给Originator,让它恢复到备份状态。结构如图15-21所示。
在这里插入图片描述

20. 状态模式

状态(State)模式能够使一个对象的内在状态改变时允许改变其行为,使这个对象看起来像是改变了其类。该模式的UML类模型如图15-22所示。
在这里插入图片描述
其中类和对象的关系为:
上下文(Context)类:定义客户应用程序有兴趣的接口;维护一个ConcreteState(具体状态)子类的实例对象。
抽象状态(State)类:定义一个接口以封装与Context的一个特别状态(State)相关的行为。
具体状态(ConcreteState)类:每一个具体状态类实现一个Context的状态相关的行为。

21. 访问者模式

访问者(Visitor)模式说明一个操作执行于一个对象结构的成员中。访问者模式让你定义一个类的新操作而无须改变它操作的这些成员类。UML类模型如图15-23所示。
在这里插入图片描述
其中类和对象的关系为:
抽象访问者(Visitor):为对象结构类中的每一个ConcreteElement的类声明一个Visit操作,这个操作的名称及标志(signature)识别传出Visit请求给访问者的类。这就使得访问者可以找到被访问的元素的具体类,也就可以直接经由其特有接口访问到元素(Element)。
具体访问者(ConcreteVisitor):实现每个由Visitor声明的操作,每个操作实现本算法的一部分,而该算法片断乃是对应于结构中对象的类。ConcreteVisitor为该算法提供了场境并存储它的局部状态。这一状态常常在遍历该结构的过程中累积结果。
元素(Element):定义一个Accept操作,它以一个访问者为参数。
具体元素(ConcreteElement):实现Accept操作,该操作以访问者为参数。
对象结构(ObjectStructure)类:能枚举它的元素;可以提供一个高层的接口以允许访问者访问它的元素;可以是一个合成模式或是一个集合,如一个列表或一个无序集合。

22. 解释器模式

给出一种语言,定义这种语言的文法的一种表示,定义一个解释器(Interpreter),用它来解释使用这种语言的句子,这就是解释器模式,其UML类模型如图15-24所示。
在这里插入图片描述
其中类和对象之间的关系为:
抽象表达式(AbstractExpression)类:定义一个接口来执行解释操作。
终结符表达式(TerminalExpression):实现文法中关联终结符的解释操作;文句中的每个终结符都需要一个实例。
非终结符表达式(NonTerminalExpression):文法中的每一条规则R::=R1R2…Rn都需要一个非终结符表达式类;维护每一条规则R1到Rn具有AbstractExpression接口实例;实现文法中关联非终结符的解释操作,采用递归的办法调用每一条规则R1到Rn的解释操作。
上下文(Context):包括解释器的所有全局信息。
客户应用程序(Client):构建由这种语言表示的句子的抽象文法树,文法树由终结符表达式或者非终结符表达式的实例组成;调用文法树中的表达式实例的解释操作。

23. 调停者模式

调停者(Mediator)模式定义一个对象封装一系列多个对象如何相互作用。Mediator使得对象之间不需要显式地相互引用,从而使其耦合更加松散。并且还让我们可以独立变化多个对象相互作用,其UML类模型如图15-25所示。其中类和对象的关系为:
抽象调停者(Mediator):定义一个接口用于与各同事对象(Colleague)之间通信。
具体调停者(ConcreteMediator):协调各个同事对象实现协作的行为;掌握并且维护它的各个同事对象引用。
同事(Colleague)类:每一个同事对象都引用一个调停者对象;每一个同事对象在需要和其他同事对象通信时,就与它的调停者通信。
在这里插入图片描述

24. 观察者模式

观察者(Observer)模式定义对象间的一种一对多依赖关系,使得每当一个对象改变状态,则其相关依赖对象皆得到通知并被自动更新,其UML类模型如图15-26所示。
在这里插入图片描述
其中类和对象的关系为:
被观察对象(Subject):了解其多个观察者,任意数量的观察者可以观察一个对象;提供一个接口用来绑定及分离观察者对象。
具体被观察对象(ConcreteSubject):存储具体观察者(ConcreteObserver)有兴趣的状态;当其状态改变时发送一个通知给其所有的观察者对象。
观察者(Observer):定义一个更新接口,在一个被观察对象改变时应被通知。
具体观察者(ConcreteObserver):维护一个对ConcreteSubject对象的引用;存储状态,状态需与ConcreteSubject保持一致;实现观察者更新接口以保持其状态与ConcreteSubject对象一致。

25. MVC基础

MVC模式是“Model-View-Controller”的缩写,中文翻译为“模式-视图-控制器”。它把一个应用的输入、处理、输出流程按照Model、View、Controller的方式进行分离,这样一个应用被分成三个层——模型层、视图层、控制层。
视图(View)代表用户交互界面,对于Web应用来说,可以概括为HTML界面,但有可能为XHTML、XML和Applet。而一个应用可能有很多不同的视图,MVC设计模式对于视图的处理仅限于视图上数据的采集和处理,以及用户的请求,而不包括在视图上的业务流程的处理,业务流程的处理交予模型(Model)处理。
模型(Model):就是业务流程/状态的处理以及业务规则的制定。业务流程的处理过程对其他层来说是黑箱操作,模型接受视图请求的数据,并返回最终的处理结果。业务模型的设计可以说是MVC最主要的核心。业务模型还有一个很重要的模型那就是数据模型。数据模型主要指实体对象的数据保存(持续化)。
控制(Controller)可以理解为从用户接收请求,将模型与视图匹配在一起,共同完成用户的请求。划分控制层的作用也很明显,它清楚地告诉你,它就是一个分发器,选择什么样的模型,选择什么样的视图,可以完成什么样的用户请求。控制层并不做任何的数据处理。
模型、视图与控制器的分离,使得一个模型可以具有多个显示视图。如果用户通过某个视图的控制器改变了模型的数据,所有其他依赖于这些数据的视图都应反映到这些变化。因此,无论何时发生了何种数据变化,控制器都会将变化通知所有的视图,导致显示的更新。这实际上是一种模型的变化-传播机制。

习题

试题1
设计模式中的__(1)模式将对象组合成树形结构以表示“部分一整体”的层次结构,使得客户
对单个对象和组合对象的使用具有一致性。下图为该模式的类图,其中,
(2)定义有子部件的那
些部件的行为;组合部件的对象由
(3)__通过component提供的接口操作。
在这里插入图片描述
(1)A.代理(Proxy)B.桥接器(Bridge)
C.组合( Composite)D.装饰器(Decorator)
(2)A.Client B.Component C.Leaf D.Composite
(3)A.Client B.Component C.Leaf D.Composite

试题2
欲动态地给一个对象添加职责,宜采用__(4)__模式。
(4)A.适配器(Adapter)B.桥接(Bridge)
C.组合( Composite) D.装饰器(Decorator)

试题3
__(5)__模式通过提供与对象相同的接口来控制对这个对象的访问。
(5)A.适配器( Adapter) B.代理(Proxy)
C.组合( Composite) D.装饰器(Decorator)

试题4
__(6)__将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起
工作的那些类可以一起工作。
(6)A.Adapter(适配器)模式 B.Command(命令)模式
C.Singleton(单例)模式 D.Strategy(策略)模式

试题5
以下关于单身模式(Singleton)的描述中,正确的是__(7)__。
(7)A.它描述了只有一个方法的类的集合
B.它能够保证一个类只产生一个唯一的实例
C.它描述了只有一个属性的类的集合
D.它能够保证一个类的方法只能被一个唯一的类调用

试题6
__(8)__设计模式定义了对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,
所有依赖于它的对象都得到通知并自动刷新。
(8)A.Adapter(适配器)B.Iterator(迭代器)
C.Prototype(原型)D.Observer(观察者)

答案
试题1分析
本题考查组合设计模式。组合设计模式将对象组合成树形结构以表示“部分一整体”的层次结
构,使得客户对单个对象和组合对象的使用具有一致性。
在类图中,Component为合成的对象声明接口;某些情况下,实现从此接口派生出所有类共有
的默认行为,定义一个接口可以访问及管理它的多个部分(GetChild),如果必要也可以在递归结
构中定义一个接口访问它的父节点,并且实现它;Leaf在合成中表示叶节点对象,叶节点没有子节
点;Composite用来定义有子节点(子部件)的部件的行为,存储子节点(子部件);Client通过
Component接口控制组合部分的对象。
试题1答案
(1)C(2)D(3)A
试题2分析
本题考查设计模式的应用场合,题目中的几种设计模式在前文中已有详细描述。这几个模式的
核心特点可以总结为:
适配器模式将一个接口转换成为客户想要的另一个接口,适配器模式使接口不兼容的那些类可
以一起工作。
桥接模式将抽象部分与实现部分分离,使得它们两部分可以独立地变化。
组合模式组合多个对象形成树型结构以表示整体—部分的结构层次。
装饰器模式动态地给一个对象增加其他职责,就增加对象功能来说,装饰模式比生成子类实现
更为灵活。
通过总结可以得知,4个备选设计模式中,装饰器模式最吻合。
试题2答案
(4)D
试题3分析
与试题2类似,本题也是考查设计模式的应用场合,关于适配器、组合、装饰器的特点前面已经
介绍,不再赘述。
代理模式通过提供与对象相同的接口来控制对这个对象的访问。
试题3答案
(5)B
试题4分析
适配器模式的意图就是将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不
兼容而不能一起工作的那些类可以一起工作。
命令模式的意图是将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;
对请求排队或记录请求日志,以及支持可撤消的操作。
单例模式的意图是确保某个类只有一个实例,且能自行实例化,并向整个系统提供这个实例。
策略模式的意图是定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换,该模
式使得算法可独立于使用它的客户而变化。
试题4答案
(6)A
试题5分析
此题属于纯概念题,单身模式的提出,其意图就是保证一个类仅有一个实例,并提供一个访问
它的全局访问点。所以本题选B。
试题5答案
(7)B
试题6分析
本题考查内容涉及的设计模式包括:适配器、迭代器、原型、观察者。考查的正是这些模式的
定义,相关知识参看本节考点精讲。
试题6答案
(8)D

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值