第 3 章 概要设计 ( 第 3.4-3.6 节)

Preview:

DESCRIPTION

第 3 章 概要设计 ( 第 3.4-3.6 节). 主要内容. 面向对象设计方法 面向对象软件设计模式 MVC 框架. 3.4 面向对象的设计方法. 一个经过良好设计的对象是软件基本的建造块,因为它对真实世界中实体的所有特征都进行了建模,但隐蔽了它的数据和对数据进行的操作的实现。 对象具有信息内聚性,这促进了复用。. 3.4.1 软件复用. 所谓软件复用是指软件开发过程中重复使用相同或相似软件元素的过程。 - PowerPoint PPT Presentation

Citation preview

中南大学 信息科学与工程学院 任胜兵

第 3 章 概要设计

( 第 3.4-3.6 节)

中南大学 信息科学与工程学院 任胜兵

主要内容

面向对象设计方法面向对象软件设计模式MVC 框架

中南大学 信息科学与工程学院 任胜兵

3.4 面向对象的设计方法

一个经过良好设计的对象是软件基本的建造块,因为它对真实世界中实体的所有特征都进行了建模,但隐蔽了它的数据和对数据进行的操作的实现。

对象具有信息内聚性,这促进了复用。

中南大学 信息科学与工程学院 任胜兵

3.4.1软件复用

所谓软件复用是指软件开发过程中重复使用相同或相似软件元素的过程。 随着面向对象技术和基于组件的技术越来越成熟,软件复用越来越被人们所认同,如应用框架、设计模式、 CORBA( Common Object Request Broker Architecture )等。

中南大学 信息科学与工程学院 任胜兵

软件复用的目标

时间性降低维护代价可靠性高效性一致性保护投资

使用者

开发者

中南大学 信息科学与工程学院 任胜兵

软件复用的对象

人员的复用 设计和功能规格说明的复用 设计模式的复用 源代码的复用 抽象模块的复用

中南大学 信息科学与工程学院 任胜兵

软件复用的阻力

管理方面 经济方面 软件部件的管理 增加的开发费用 法律方面

中南大学 信息科学与工程学院 任胜兵

软件复用对模块化结构的要求

类型可变 例程组合 实现可变 表示独立性 抽出共同的行为

中南大学 信息科学与工程学院 任胜兵

3.4.2 面向对象设计

面向对象分析的结果是得到一系列由系统分析员和用户共同确认的描述系统必须“做什么”的需求分析模型。面向对象设计的主要目的则是将分析阶段得到的需求分析模型转化为“怎么做”的设计模型。

中南大学 信息科学与工程学院 任胜兵

子系统设计 子系统设计准则: 子系统应该具有良好定义的接口; 除“通信类”外,子系统的其它所有类都只能与子

系统内部的类通信; 子系统的数目应该尽可能少 ; 子系统内部仍然可以进一步分解成更小的子系统以

降低复杂性。一般地说,每个子系统可以进一步划分为最常见的四个部件:问题域部件,人机交互部件、数据管理部件和系统交互部件。

中南大学 信息科学与工程学院 任胜兵

问题域部件的设计

有时候,面向对象需求分析的结果可以不加修改直接作为面向对象设计中的问题域部件的设计。修改: 将多重继承结构改为单重继承结构以便能够用只有

单重继承的面向对象程序设计语言实现; 又如修改分析的结果以复用实现库中已有的类; 增加保存临时结果的属性以提高速度; ….

中南大学 信息科学与工程学院 任胜兵

人机交互部件的设计

人机交互部件突出人如保命令系统以及系统如何向用户提供交互信息。 在设计人机交互部件时,首先考虑的是人,其次是任务,然后再是有关工具。 人机交互部件在系统行为和用户界面之间架起了一座桥梁。

中南大学 信息科学与工程学院 任胜兵

交互设计准则

一致性,即使用一致的术语,一致的步骤、一致的动作等;及时提供反馈信息;并且应简短、直接、及时从户角度作出提示;提供撤消命令;减少用户记忆负担,如每步给出足够的提示;易学,富有吸引力,如提供联机帮助,充分利用图形用户界面的优越性等。

中南大学 信息科学与工程学院 任胜兵

人机交互部件类的设计

人机交互的形式有多种多样,如对话、菜单、窗口、按钮、图符、表格、命令语言等等。 人机交互部件类的设计目的是决定使用哪种方式的人机交互,并标识有关的人机交互对象 &类。 人机交互部件的设计在一定程度上依赖于所使用的用户接口。

中南大学 信息科学与工程学院 任胜兵

注意事项

不是改变用户行为去适应系统的人机交互界面,而是反之;一个好的用户界面总是能在工作中引导用户完成其工作,而不是强迫用户按某种特定方式工作。最好由用户开发的场景或使用用例来驱动用户界面。

中南大学 信息科学与工程学院 任胜兵

数据管理部件的设计

数据管理部件的对象 &类用来对系统生成的永久数据进行访问和管理。设置数据管理部件可以将特定的数据管理技术从问题域部分分离开来,有利开系统的维护。

中南大学 信息科学与工程学院 任胜兵

主要活动

选择数据存储管理模式:普通文件管理系统、关系数据库管理系统和面向对象数据库管理系统。 数据存放格式设计(一项重要的工作便是消除数据冗余)。设计数据管理操作和属性。

中南大学 信息科学与工程学院 任胜兵

例子

检索信息获取信息

显示租用状态

激活租用事务

系统准备好SaleRentWindow RentalTransaction AVItem AVItemDMSalesman

准备租用

人机接口: 问题域: 数据管理:

扫描条形码

获取信息

返回信息

返回信息返回信息

显示信息

更新信息获取信息

更新租用信息确认租用

更新信息

返回信息

返回信息返回信息

显示信息

中南大学 信息科学与工程学院 任胜兵

系统交互部件的设计

系统交互部件主要负责系统与系统中的物理设备之间、各个子系统之间、以及系统与其它系统之间的通信和数据交换。 系统交互部件的设计主要是标识一些对象 &类,负责处理并发、中断、调度(操作系统级)以及其它有关特定平台的一些问题。

中南大学 信息科学与工程学院 任胜兵

事件驱动型交互

事件驱动型交互由事件触发(事件常是表明某些数据到达的信号),这些交互可能负责与设备、屏幕窗口、子系统或其它任务等通信。

数据线或其它数据源中断任务苏醒

阅读数据处理数据

结束处理

任务睡眠

中南大学 信息科学与工程学院 任胜兵

时钟驱动型交互

时钟驱动型交互按特定的时间间隔被触发过进行某些处理。这类交互要适用于某些人机接口、子系统、任务或其它系统周期性地通信。

任务设置睡眠时间后转入睡

眠系统中断

任务苏醒通知任务

任务处理

结束处理

中南大学 信息科学与工程学院 任胜兵

其他活动

识别优先交互和关键交互;识别交互协调者;审查各个交互;定义各交互。

中南大学 信息科学与工程学院 任胜兵

对象设计

根据面向对象分析阶段得到的对象模型(主要是问题域的对象模型),以及面向对象设计阶段特别是子系统设计中各个部件的设计中得到的对象模型,对这些对象模型进一步求精而得到每一个对象的更为准确的属性,然后设计出这些属性相应的数据结构。 有关对象设计的内容,实际上是详细设计的工作。

中南大学 信息科学与工程学院 任胜兵

消息设计

消息设计是指要描述每一个对象可以接收和发送的消息接口。消息设计的一个很好的出发点是对象模型中的对象与对象之间的关系。对象与对象的事件跟踪图也是消息设计的另一个出发点。

中南大学 信息科学与工程学院 任胜兵

方法设计

方法设计是指在面向对象设计阶段根据面向对象的行为模型和功能模型,进一步对每一个对象的方法进行求精,一方面是要将以前遗漏了的方法找出来,一方面是要定义每一种方法的过程化的细节。

详细设计将继续讨论

中南大学 信息科学与工程学院 任胜兵

3.5面向对象软件设计模式 面向对象设计模式最初出现于 70 年代末 80年代初。1987 年W.Cunningham 和 K. Beck引入建筑师 C.Alexander 的模式概念。 面向对象设计模式是普通面向对象设计问题的解决方案,这类问题以一组交互类的形式出现,用户根据需要定制这些交互类以形成专门的设计。作用:设计模式不仅使人们可以更加方便地复用成功设计方案,也能提高已有系统的文档管理和系统维护的有效性。

中南大学 信息科学与工程学院 任胜兵

3.5.1设计模式的描述与分类 一个设计模式事实上是系统地命名、解释和评价某一重要的可重现的面向对象设计方案。所有设计均可从四个方面加以描述: 模式名称:用一至两个词描述设计问题、解决方案和效果。模

式名称便于使用者在更高的抽象层次上进行设计并交流有关设计思想。

问题描述:指明使得设计模式可以被应用所必须存在的环境条件。它解释了设计问题及其背景。

解决方案:描述了设计方案的组成部分,它们之间的关系及各自的职责和协作方式。

效果:描述应用设计模式后的结果及使用模式应权衡的问题。

中南大学 信息科学与工程学院 任胜兵

Gamma分类类别 设计模式名称 意图简要说明

创建型模式

抽象工厂( Abstract Factory)

提供创建相关的或相互依赖的一族对象的接口而无需指定具体的类。

生成器 (Builder) 将一个复杂对象的创建与它的表示分离,使得同样的构建过程可以创建不同的表示。

工厂方法 (Factory Method)

定义一个用于创建对象的接口,由子类决定实例化哪一个类。

原型( Prototype )

使用一个原型指定要创建的类的类型,通过拷贝这个原型得到新的对象。

单件 (Singleton) 保证一类仅有一个实例,并提供一个全局性的访问点。

中南大学 信息科学与工程学院 任胜兵

Gamma分类

结构型模式

适配器 ( Adapter ) 将一个类的接口转换成用户希望得到的另一种接口,使原来由于接口不相容而不能一起工作的类可一起工作。

桥( Bridge ) 将类的抽象部分与它的实现部分分离,使它们可以相互独立地变化。

组合( Composite )

将对象组成树结构来表示局部和整体的层次关系,使单个对象和组合对象的使用具有一致性。

装饰 ( Decorator ) 动态地给一个对象添加新功能。

外观 ( Façade ) 给一个子系统的所有接口提供一个统一接口,使子系统便于使用。

轻量 (Flyweight) 运用共享技术有效地支持大量细粒度对象。

类别 设计模式名称 意图简要说明

中南大学 信息科学与工程学院 任胜兵

Gamma分类

行为模式

职责链 ( Chain of Responsibility)

将多个接收请求的对象连成一条链,并沿链传递请求,直到有一个对象处理它为止。避免了请求的发送者和接收者之间的耦合。

命令( Command) 将一个请求命令封闭优一个对象,便于将不同的请求参数化;对请求排对或记录请求日志,以及支持可撤消请求的操作。

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

迭代器( Iterator ) 提供一种顺序访问一个聚合对象中各元素又不暴露对象内部表示的方法。

中介者 ( Mediator ) 定义一个中介对象封装一系列对象的交互。

备忘录 (Memento) 在不破坏封装的条件下,获得一个对象的内部状态并将它外部化,从而在以后可使对象恢复到这个状态。

观察者 ( Observer ) 定义对象一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象均得到通知并被自动更新。

状态 ( State ) 允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎能修改它的类。

策略 (Strategy) 定义一系列算法,把它们均封闭起来,并且使它们可相互替换。它使算法可独立于使用者而变化。

模板方法 ( Template Method) 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,从而使子

类可以不改变算法的结构即可重定义该算法的某些特定步骤。访问者 ( Visitor ) 描述一个作用于某对象结构中各元素的操作,从而可以在不改变被操作

元素类的条件下定义新的操作。

类别 设计模式名称 意图简要说明

中南大学 信息科学与工程学院 任胜兵

3.5.2创建型模式

创建型模式帮助系统独立于对象的产生、组合和表示。作用:一方面均将关于系统使用哪些具体的类的信息封装起来;另一方面隐蔽了这些具体类的实例是如何被创建和放在一起的。因此,创建型模式在“什么”被创建、“怎样”被创建、“谁”创建它以及“何时”创建等方面带来了很大的灵活性,有利于设计可复用的软件成分。

中南大学 信息科学与工程学院 任胜兵

工厂方法模式(结构)

《 interface》Creator

《 interface》Product

ConcreteProduct

factoryMethod( )

ConcreteCreator

factoryMethod( )

《 creates》

Client

中南大学 信息科学与工程学院 任胜兵

产品 /具体产品类 Product 定义工厂方法生成的对象的接口。例如: ( Java 程序)public interface Product { // 产品的接口声明}

Concrete Product 实现 Product 类的接口。例如:public class ConcreteProduct implements Product {

// 构造函数

public ConcreteProduct( ) {

// do something

}

//产品接口实现

}

中南大学 信息科学与工程学院 任胜兵

创建者 /具体创建者类Creator声明一个工厂,返回一个 Product 类型的对象。也可定义工厂方法的缺省

实现。可调用工厂方法生成一个 Product 对象。例如:public interface Creator { //工厂方法接口声明 public Product factoryMethod();}

Concrete Creator 重定义工厂方法以返回适当的 Concrete Product 实例。例如:public class ConcreteCreator implements Creator{ //工厂方法实现 public Product factoryMethod( ) { return new ConcreteProduct( );}}

中南大学 信息科学与工程学院 任胜兵

客户类

Client仅使用由 Creator 和 Product声明的接口。例如:public class Client { private static Creator creator; private static Product product; public static void main(String[] args) { creator = new ConcreteCreator(); product = creator.factoryMethod(); // do other things}}

中南大学 信息科学与工程学院 任胜兵

使用条件

一个类不知道它所必须创建的对象的类。一个类希望由其子类确定它创建的对象。类将创建对象的职责委派给多个帮助者子类中的一个,且希望将哪一个帮助者子类是代表者这一信息局部化。

依赖倒置原则

中南大学 信息科学与工程学院 任胜兵

使用效果 比直接产生对象更灵活。“工厂方法”给子类一个挂钩,以便在子类中扩展。连接平行类层次。当一个类将它的一些职责委托给一个独立的类的时候,就会产生平行类层次。

《 interface》Figure

createManipulator( )

《 interface》Manipulator

downClick( )upClick( )

drag( )

LineManipulatordownClick( )

upClick( )drag( )

TextManipulatordownClick( )

upClick( )drag( )

TextFigurecreateManipulator()

LineFigurecreateManipulator()

Client

中南大学 信息科学与工程学院 任胜兵

结论

工厂方法模式在遵循依赖倒置原则方面有重要意义,使得高层策略模块在创建类的实例时无需依赖具体的类。也使得一组类的完全不同序列的实现间进行交换成为可能。工厂方法模式会带来复杂性。

中南大学 信息科学与工程学院 任胜兵

抽象工厂模式结构

《 interface》AbstractFactory

createProductA( )createProductB( )

ConcreteFactory2

createProductA( )createProductB( )

ConcreteFactory1

createProductA( )createProductB( )

《 interface》AbstractProductA

ConcreteProductA1 ConcreteProductA2

《 interface》AbstractProductB

ConcreteProductB1 ConcreteProductB2

Client

中南大学 信息科学与工程学院 任胜兵

抽象工厂 /具体工厂类Abstract Factory声明创建抽象产品对象的操作接口。例如:public interface AbstractFactory { // 产品等级结构 A 的工厂方法 public AbstractProductA createProductA();// 产品等级结构 B 的工厂方法 public AbstractProductB createProductB();}

ConcreteFactoryl实现创建具体产品对象的操作。例如:public class ConcreteFactory1 {//产品族 1的具体工厂类 // 产品等级结构 A 的工厂方法 public AbstractProductA createProductA() {return new ConcreteProductA1( );}// 产品等级结构 B 的工厂方法 public AbstractProductB createProductB() {return new ConcreteProductB1( );}}//产品族 2 的具体工厂类的实现与产品族 1的具体工厂类类似

中南大学 信息科学与工程学院 任胜兵

抽象产品 /具体产品类AbstractProductA声明一种产品对象的接口。例如:public interface AbstractProductA { //接口声明}//AbstractProductB 与 AbstractProductA 类似

ConcreteProductA1定义将被相应的具体工厂类创建的产品对象;实现抽象产品类接口。例如:

public class ConcreteProductA1 implements AbstractProductA { //构造函数public ConcreteProductA1( ){}//接口实现}//其它产品类的定义与 ConcreteProductA1类似

中南大学 信息科学与工程学院 任胜兵

客户类Client仅使用由抽象工厂类和抽象产品类声明的接口。例如:public class Client { private static AbstractFactory factory1; private static AbstractFactory factory2; private static AbstractProductA productA; private static AbstractProductB productB; public static void main(String[] args) { factory1 = new ConcreteFactory1( ); factory2 = new ConcreteFactory2( ); productA = factory1.createProductA( ); productB = factory2.createProductB( ); // do other things}}

中南大学 信息科学与工程学院 任胜兵

使用条件

系统应与如何创建、组合和表示其产品无关。系统应由多个产品族之一来配置。强调一系列相关产品对象的设计以便联合使用。提供一个产品类库,但只想显示它们的接口。

中南大学 信息科学与工程学院 任胜兵

使用效果

隔离了具体的类。使产品族间的转换容易进行。容易实现一个应用一次只使用同一个系统中的产品对象。难以扩展“抽象工厂”以支持新种类的产品。

不符合开闭原则

中南大学 信息科学与工程学院 任胜兵

3.5.3 结构型模式

结构型模式涉及如何组合类和对象构成更大的结构。一种方法是采用继承机制来组合接口或实现来形成更大的结构;另一种方法通过对象组合方式对一些对象进行组合来形成。由于对象组合可以在运行时刻改变,而继承机制为静态类组合,因而对象组合方式具有更大的灵活性。

中南大学 信息科学与工程学院 任胜兵

适配器模式结构

Client

Adaptee

operation( )

《 interface》

Targetrequest( )

Adapter

request( )

利用继承机制

Client

Adaptee

operation( )

《 interface》Target

request( )

Adapter

request( )

利用组合机制

中南大学 信息科学与工程学院 任胜兵

目标 /被适配者类Target 定义客户类使用的与特定领域相关的接口。例如:public interface Target { //定义用户期望的接口 public void request( );}

Adaptee 定义一个被用来适配的已存在的接口。例如:public class Adaptee { //被适配的接口 public void operation( ){// do something}}

中南大学 信息科学与工程学院 任胜兵

适配器类(利用继承机制)

Adapter适配 Adaptee 类中的接口至 Target 类中的接口。例如://利用继承机制public class Adapter extends Adaptee implements Target { //适配 operation 为 request public void request( ) { //调用 operation operation( );}}

中南大学 信息科学与工程学院 任胜兵

适配器类(利用组合机制)// 利用对象组合public class Adapter implements Target { private Adaptee adaptee; // 构造函数 public Adapter(Adaptee adaptee) { this.adaptee = adaptee;}//适配 operation 为 request public void request( ) { // do other things adaptee.operation( ); // do other things}}

中南大学 信息科学与工程学院 任胜兵

客户类

Client 使用 Target 类中的接口。例如:// 利用继承机制public class Client { private static Target target;public static void main(String[] args) { target = new Adapter( ); // 以后可通过调用 target.request( )调用 adaptee 定义的

operation( ) // do other things}}

中南大学 信息科学与工程学院 任胜兵

客户类// 利用对象组合public class Client { private static Target target; private static Adaptee adaptee; public static void main(String[] args) { target = new Adapter(adaptee); // 以后可通过调用 target.request( )调用 adap

tee 定义的 operation( ) // do other things}}

中南大学 信息科学与工程学院 任胜兵

使用条件

希望使用一个已存在的类,它的接口却与希望的接口不匹配。要创建一个可复用的类,该类可以与其它不相关的类或不可预见的类协同工作。想使用一些已存在的类,但不能对每一个类子类化以匹配它们的接口(仅适用于对象组合的适配器模式)。

中南大学 信息科学与工程学院 任胜兵

使用效果

a、对利用继承机制的情况:当想要匹配 Adaptee 类及其所有子类时, Adapt

er 类将不能胜任。 Adapter 类可以重定义 Adaptee 类的行为。 不需要间接指针以得到 adaptee 对象。

b 、对利用对象组合的情况:允许一个 Adapter 类与多个 Adaptee 类一起工

作。 重定义 Adaptee 类的行为比较困难。

中南大学 信息科学与工程学院 任胜兵

组合模式(结构)

Client《 interface》Component

operation( )add(Component)Remove(Component)getChild(int)

Leafoperation( )

Compositeoperation( )add(Component)Remove(Component)getChild(int)

children

中南大学 信息科学与工程学院 任胜兵

部件类

Component 为组合中的对象声明接口;在适当的情况下实现所有类共有接口的缺省行为;声明接口用于访问和管理组合对象中的子部件。例如:

public interface Component { // operation public String toString( ); //声明接口public void add(Component component); public void remove(Component component); public Component getChild(int index);}

中南大学 信息科学与工程学院 任胜兵

叶子类Leaf代表部件中的叶子对象,它没有子部件;定义组合对象中原始对象的行为;对与子部件有关的操作接口实现为空。例如:

public class Leaf implements Component { protected int id = 0; //标识号 public Leaf(int id) { this.id = id; } public String toString( ) { return( “ I am Leaf (ID “ +id+

“)” ); } public void add(Component component) { } public void remove(Component component) { } public Component getChild( int index) { return null; }}

中南大学 信息科学与工程学院 任胜兵

组合类Composite 定义有子部件的部件的行为;存储子部件;实现 Component 类接口中与子

部件有关的操作。例如:import java.util.LinkedList;public class Composite implements Component { protected LinkedList children = new LinkedList( ); protected int id = 0; //标识号 public Composite(int id) { this.id = id;} public String toString( ) { return(“I am Composite (ID” +id+ “)”); } public void add(Component component) { this.children.add(component);} public void remove(Component component) { this.children.remove(component); }public Component getChild(int index) { return (Component) children.get(index); }}

中南大学 信息科学与工程学院 任胜兵

客户类Client 通过部件类接口操作组合中的对象。例如:public class Client { public static void main(String[] args) {Component composite1 = new Composite(1);Component composite2 = new Composite(2);Component leaf1= new Leaf(1);Component leaf2= new Leaf(2);Component leaf3= new Leaf(3);composite1.add(leaf1);composite1.add(composite2);composite2.add(leaf2);composite1.add(leaf3);// do other things}}

中南大学 信息科学与工程学院 任胜兵

使用条件

希望表示对象的整体 /部分层次结构。希望一致地处理叶子对象和组合对象。

中南大学 信息科学与工程学院 任胜兵

使用效果

定义了对象的整体 /部分层次结构,且客户代码中任何用到叶子对象的地方均可使用组合对象。简化了客户代码,客户代码不必关心处理的是一个叶子对象还是组合对象,即可以一致地使用叶子对象和组合对象。易于添加新的 Composite 和 Leaf子类,客户代码不必因新的 Composite 和 Leaf子类而改变。使设计更加通用,但难于限制只组合某些特定的部件。

中南大学 信息科学与工程学院 任胜兵

3.5.4 行为型模式

行为型模式不仅描述对象或类的模式,还描述它们之间的通信模式。这些模式刻划了在运行时难以跟踪的复杂的控制流。行为型模式使设计者的注意力从控制流转移到对象间的联系方式上。

中南大学 信息科学与工程学院 任胜兵

迭代器模式结构

{abstract}Aggregate

CreateIterator( )

ConcreteAggregateCreateIterator( )

《 interface》Iterator

first( )next( )isDone( )currentItem( )

ConcreteIterator

first( )next( )isDone( )currentItem( )

Client

中南大学 信息科学与工程学院 任胜兵

迭代器类

Iterator 定义访问和遍历聚合( aggregate )对象的接口。例如:public interface Iterator { public void first( ); public void next( ); public boolean isDone( ); public Object currentItem( );}

中南大学 信息科学与工程学院 任胜兵

具体迭代器类ConcreteIterator 实现 Iterator 类中的接口;在聚合对象遍历时跟踪当前位置。例如:public class ConcreteIterator implements Iterator { private ConcreteAggregate conAgg; private int index = 0; private int size = 0; // 构造函数 public ConcreteIterator(ConcreteAggregate conAgg) { this.conAgg = conAgg; size = conAgg.size( ); index = 0;}public void first( ) { index = 0; }public void next( ) { if (index<size) { index++; }}public boolean isDone( ) { return( index>=size); }public Object currentItem( ) { return conAgg.getItem(index); }}

中南大学 信息科学与工程学院 任胜兵

聚合 /具体聚合类Aggregate 定义创建相应迭代器对象的接口。例如:abstract public class Aggregate { public Iterator createIterator( ){ return null; } }

ConcreteAggregate 实现 Aggregate 类中的接口,返回 ConcreteIterator 类的一个适当的实例。例如:

public class ConcreteAggregate extends Aggregate { private Object[] objects = {“Dog”, “Pig”, “Horse”, “Monkey”, “Mous

e”}; public Iterator createIterator( ) { return new ConcreteIterator( this); } public Object getItem( int index) { if (index<objects.length) { return objects[index]; } else { return null; } } public int size( ) { return objects.length;} }

中南大学 信息科学与工程学院 任胜兵

客户类Client引用聚集及其迭代子对象,调用迭代子对象中的操作接口实

现对聚集对象的遍历操作。例如:public class Client { private Iterator it; private Aggregate agg = new ConcreteAggregate( ); public static void main(String[] args) { it = agg.createIterator( ); while (!it.isDone( )) { System.out.println(it.currentItem( ).toString( )); it.next( ); }}}

中南大学 信息科学与工程学院 任胜兵

使用条件

在不暴露聚合对象内部表示的条件下访问聚集对象。支持对聚合对象的多种遍历。为遍历不同的聚合对象提供一个统一接口。

中南大学 信息科学与工程学院 任胜兵

使用效果

支持以不同的方式遍历聚合对象。简化了聚合对象的接口。迭代器的遍历接口使聚合对象本身不再需要类似的遍历接口。由于每个迭代器保持它自己的遍历状态,因此可以在同一个聚合对象进行多种遍历。

中南大学 信息科学与工程学院 任胜兵

观察者模式(结构)

{abstract}Subject

attach(Observer)detach(Observer)notify( )

ConcreteSubject

getState( )setState( )

subjectState

《 interface》Observer

update( )

ConcreteObserver

update( )observerState

observers

Client

中南大学 信息科学与工程学院 任胜兵

主题类Subject知道其观察者;提供接口以连接观察者对象和解除连接。例如:import java.util.Vector;import java.util.Enumeration;abstract public class Subject { private Vector observers = new Vector( ); public void attach(Observer observer) { observers.addElement(observer);} public detach(Observer observer) { observers.removeElement(observer);} public void notify( ){ Enumeration obs = ((Vector)observers.clone( )).elements( ); while (obs.hasMoreElements()) { ((Observer) obs.nextElement( )).update( );}}}

中南大学 信息科学与工程学院 任胜兵

具体主题类

ConcreteSubject存储 ConcreteObserver 对象感兴趣的状态;当其状态发生变化时向它的所有观察者发送通知( Notify)。例如:

public class ConcreteSubject extends Subject { private String subjectState = “ ”; public String getState( ) { return subjectState; } public void setState(String newState) { subjectState = newState; this.notify( ); }}

中南大学 信息科学与工程学院 任胜兵

观察者类

Observer 为那些在主题发生改变时需要获得通知的对象定义一个 update 接口。例如:public interface Observer { public void update( ); }

中南大学 信息科学与工程学院 任胜兵

具体观察者类ConcreteObserver 维护一个对 ConcreteSubject 对象的引用;存储一个与主题一致

的状态;实现 Observer 的更新接口以使自身状态与主题的状态保持一致。例如:public class ConcreteObserver implements Observer { private String observerState; private ConcreteSubject conSubject; //构造函数 public ConcreteObserver(ConcreteSubject csub) { this.observerState = csub.getState( ); this.conSubject = csub;}public void update( ) { observerState = conSubject.getState( ); System.out.println(“The state of the subject is: “+observerState);}}

中南大学 信息科学与工程学院 任胜兵

客户类Client 使用具体主题对象和观察器对象。 例如:public class Client { private static ConcreteSubject subject; private static Observer observer; public static void main(String[] args) { subject = new ConcreteSubject( ); observer = new ConcreteObserver(subject); subject.attach(observer); subject.setState(“Start”); // do other things} }

中南大学 信息科学与工程学院 任胜兵

使用条件

一个模型有两个方面,其中一方面依赖于另一方面。将二者分别封装在独立的对象中可使它们可以各自独立地改变和复用。 一个对象的改变需要同时改变其它对象,且不知道有多少对象需改变。一个对象必须能够在对别的对象一无所知的情况下通知它们。

中南大学 信息科学与工程学院 任胜兵

使用效果

减少了 Subject 类和 Observer 类之间的耦合。支持广播通信。主题发送的通知不需指定它的接收者。处理还是忽略一个通知取决于观察者。可能会发生预想不到的更新。在主题上一个看似无关紧要的操作可能会引起一系列对观察者以及依赖这些观察者的那些对象的更新。

中南大学 信息科学与工程学院 任胜兵

访问者模式 《 interface》

Visitor

visit(ElementA)visit(ElementB )

ConcreteVisitor1

visit(ElementA)visit(ElementB)

ConcreteVisitor2

visit(ElementA)visit(ElementB)

《 interface》Element

accept(Visitor )

ElementA

accept(Visitor)operationA( )

ElementB

accept(Visitor)operationB( )

ObjectStructure

operation(Visitor )add(Element)

Client

中南大学 信息科学与工程学院 任胜兵

各参与类的职责 访问者( Visitor ):为 Object Structure 中的每一个具体 Element 类声明一个访问操作 visit 。 具体访问者类( ConcreteVistitor1, ConcreteVisitor2 ):实现 Visitor声明的每一个接口。 对象结构类( Object Structure ):可枚举其元素;可提供一个高级接口 operation ,允许访问其元素;可以是一个组合或是一个集合。元素类( Element ):定义一个以 Visitor 类为参数的 Accept 操作接口。具体元素( ElementA, ElementB ):主要实现 Element 类中定义的 Accept 操作。 客户类( Client ):引用 Visitor 对象和 ObjectStructure 对象。

中南大学 信息科学与工程学院 任胜兵

使用条件

一个对象结构包含很多类对象,它们有不同的接口,希望对这些对象实施一些依赖于其具体类的操作;需对一个对象结构中的对象进行很多不同且不相关的操作,而希望避免这些操作“污染”这些对象的类;定义对象结构的类很少变动,但对这个结构的操作经常改变。

中南大学 信息科学与工程学院 任胜兵

使用效果 易于在对象结构上定义新的操作,增加新的访问者即可;可将相关的操作集中在一个访问者中,无关行为分别放在各自的访问者子类中;难以增加新的具体的 Element 类;访问者可对具有不同元素类型的对象结构进行访问,而迭代器却不能胜任;该模式常须提供访问元素内部状态的公共操作,破坏访问元素的封装性。

中南大学 信息科学与工程学院 任胜兵

3.6 MVC 框架

从复用的角度来看,类作为复用单元往往太小,而且类本身也很少完成有用的功能,需要与其它类一起协作。应用框架是一组协同类,用来为一族相关应用提供可复用的基础设施,包括设计和源代码。微软的基础类库( Microsoft Foundation Class MFC )便是为Windows 应用程序提供的创建 GUI界面的框架。 SWING 是 Sun公司提供的创建 Java应用程 GUI界面的框架。 JUnit 框架用于 Java测试。

中南大学 信息科学与工程学院 任胜兵

应用框架的特点 模块化 :框架能过将易变的实现细节隐藏在稳定的接口之中,更加强化了模块化的特征。 复用性 :应用框架的代码复用简化了应用的开发。同时,应用框架也提供了可复用的抽象算法和高层设计以及交流所用的词汇(分析)。可扩展性:应用框架常利用挂勾( Hook )方法来允许新的应用扩展框架的有关接口,从而增强了框架的可扩展性。控制倒置 :是应用框架而不是应用来决定应用的哪些具体方法响应有关外部事件。

中南大学 信息科学与工程学院 任胜兵

应用框架的分类

根据复用方式的不同,应用框架可分为三类:白盒框架、灰盒框架和黑盒框架。 根据框架涉及的范围不同,框架又可分为三类:系统基础设施框架、中间件集成框架和企业应用框架。 根据框架与应用之间的关联程度,又可分为水平框架(横向框架)和垂直框架(纵向框架)。

中南大学 信息科学与工程学院 任胜兵

MVC 框架

模型-视图-控制器( Model-View-Controller , MVC )框架结构是为那些需要为同一数据提供多个视图的应用程序而设计的,它很好的实现了数据层与表示层的分离。

中南大学 信息科学与工程学院 任胜兵

MVC 框架中类的交互 当用户进行一些输入动作后,控制器接收用户事件,并根据事件的类型来改变模型;视图事先会在模型中登记,当模型数据发生改变时,马上通知已向此模型登记的每个视图,视图从模型中取得最新的数据并刷新自己。

中南大学 信息科学与工程学院 任胜兵

MVC 框架适配

MVC 是一种通用的 GUI框架;Java SWING是 MVC 框架的一种适配;在 Smalltalk-80 v2.0 中也存在 MVC 框架的一种适配。

中南大学 信息科学与工程学院 任胜兵

库 /设计模式 /框架 /体系结构复用比较

库 设计模式 框架

体系结构

功能

控制