面向对象系统设计循序渐进.docx
《面向对象系统设计循序渐进.docx》由会员分享,可在线阅读,更多相关《面向对象系统设计循序渐进.docx(31页珍藏版)》请在冰豆网上搜索。
面向对象系统设计循序渐进
面向对象系统设计
循序渐进(第一版)
OOD循序渐进
作为一名软件开发人员,我深刻地体会到面向对象系统设计带来的种种便利:
1、良好的可复用性。
开发同类项目的次数与开发新项目的时间成反比,谁也不愿做重复劳动吧。
2、易维护。
基本上不用花太大的精力跟维护人员讲解,他们可以自己读懂源程序并修改了,要不然开发的系统越多,你的负担就越重,不是吗?
。
3、良好的可扩充性。
以前,在向一个用结构化思想设计的庞大系统中加一个功能则必须考虑兼容前面的数据结构、理顺原来的设计思路,即使客户愿意花钱修改,作为开发人员多少都有点恐惧。
在向一个用面向对象思想设计的系统中加入新功能,不外乎是加入一些新的类,基本上不用修改原来的东西,这种感觉真爽。
前言
本书是一本介绍面向对象软件系统设计的书,从组织结构上分为两大部分:
面向对象的概念与UML概述、面向对象系统设计。
第一部分是基础,第二部分是核心。
本书对面向对象概念和UML语言的介绍并不是面面具到,介绍的基本上是本书需要用到的那部分内容,所有不适合作为面向对象概念或UML语言的参考手册。
阅读本书的基础
●至少熟悉一种编程语言,最好熟悉的是面向对象编程语言。
●对软件工程有一定的了解。
●如果你只有结构化思想的开发经验,那么阅读本书后会对你有所启发。
●如果你有面向对象思想的开发经验,那么就让我们一起来探讨吧。
阅读指南
如果你已经熟悉了面向对象概念,当我提到“封装”、“消息”、“对象类”等术语时,你可以不查阅资料,那么你可以跳过第一、第二章,直接阅读第三章的内容,否则你还是从头看起。
建立共同语言
为了避免在下面的讨论中因一些名称的问题而产生错误的理解,我觉得有必要先说明一下我的一些口语习惯和一些中英文名称对应关系。
叙述中具体使用哪个名词或用中文还是英文,要根据具体上下文而定。
如:
我是计算机专业的。
我买了一台手提电脑。
其中计算机和电脑都是指Computer。
下面是部分中英文对照表:
英文
中文
简称
ObjectOriented
面向对象
OO
ObjectOrientedAnalysis
面向对象分析
OOA
ObjectOrientedDesign
面向对象设计
OOD
ObjectOrientedProgramming
面向对象的程序设计
OOP
UnifiedModelingLanguage
统一建模语言
UML
Actor
活动者
UseCase
用例
Class
对象类、类
Attribute
属性
Operation
操作、方法
Interface
接口
Component
组件
Package
包
Node
接点
Association
关联
Composition
组合
Aggregation
聚合
Generalization
泛化
Dependency
依赖
Realization
实现
Message
消息
State
状态
Comment
注释
面向对象的概念与UML概述
第一章、面向对象的概念与UML概述
1.1分析与设计概述
首先来看看我们认识事物的过程:
当接触一个新事物时,就会问这个东西是干什么用的?
进一步的,怎么使用呢?
改造事物的过程:
它需要改进吗
要改进什么?
如何改进呢?
它需要改进吗?
要改进什么?
如何改进呢?
从接触新事物到要改进什么,可以总结为是对事物的分析。
如何改进可以总结为是对目标(改进后)事物的设计。
这个事物是一个对象。
再来看看我们开发软件的分析、设计过程:
当接触到一个系统时,首先了解当前系统提供什么服务、当前系统的服务如何操作,再分析目标系统必须提供什么服务,目标系统提供的这些服务如何操作,进而考虑如何实现这些服务(这里的实现是逻辑上的,指系统设计,程序设计是指物理上的实现)。
1.1.1系统分析
系统分析是指对当前系统和对目标系统进行抽象。
可以分为当前系统分析和目标系统分析。
对于分析的结果可以建立当前系统分析模型和目标系统分析模型(后面会详细讨论)。
它用来表达当前系统提供什么服务、当前系统的服务如何操作,目标系统必须提供什么服务,目标系统提供的这些服务如何操作等问题。
建立分析模型的方法有很多,常用的有面向数据流的分析方法(SA)和面向对象分析方法(OOA)等。
1.1.2系统设计
系统分析主要关心系统必须做什么,而不必太多的考虑其中的实现细节,它注重的是问题领域与系统责任。
系统设计就要考虑实现的细节问题了,它主要说明如何实现分析中的元素,注重的是实现相关的问题,并做为实施阶段的依据。
一般包括:
软件架构设计、子系统设计、详细设计和数据库设计。
常用的方法与系统分析相对应有面向数据流的设计方法(SD)和面向对象设计方法(OOD)等
1.1.3面向对象方法
面向对象是认识事物的一种方法。
用面向对象方法来认识青蛙
1.2面向对象的概念
面向对象(OO)是认识事物的一种方法,是一种以对象为中心的思维方式。
这里介绍它的几个主要概念:
对象、类、封装、继承、多态性、消息、关联。
1、对象
世界上所有的事物都可以称为对象。
对象可以是有形的如:
一台电视机等。
也可以是无形的如:
帐户、一项记录等。
对象具有静态特征和动态特征。
一个对象就是一个独立存在的客观事物,它由一组属性和对属性进行操作的一组操作构成。
属性和操作是对象的两大要素。
属性是对象静态特征的描述,操作是对象动态特征的描述。
对象名也称为对象标识。
如电视的属性有:
品牌、尺寸、重量等。
操作有:
收视、选台、音量调节等。
2、类
根据抽象的原则对客观事物进行归纳和划分,只关注与当前目标相关的特征,把具有相同特征的事物归为一个类。
它是一个抽象的概念。
类是具有相同属性和相同操作(服务)的对象的集合。
它包括属性和操作(注:
类的服务和操作只是叫法上的区别)。
对象
客观世界中的每一匹马都属于动物类,其中的一匹马就是动物类的一个实例,即一个动物对象。
3、封装
封装是指按照信息屏蔽的原则,把对象的属性和操作结合在一起,构成一个独立的对象。
外部对象不能直接操作对象的属性,只能使用对象提供的服务。
我们不用关心电视机的内部工作原理,
电视机提供了选台、调节音量等功能让我们使用。
4、继承
继承表达了对象的一般与特殊的关系。
特殊类的对象具有一般类的全部属性和服务。
机动车具有车的全部属性和服务,同样汽车具有机动车的全部属性和服务。
一般和特殊是相对而言的,在车和机动车之间,车是一般类(基类、超类、父类),机动车是特殊类(子类);在机动车和汽车之间机动车是一般类,汽车是特殊类。
继承具有传递性,如汽车具有车的全部属性和服务。
5、消息
向某个对象发出的服务请求称作消息。
对象提供的服务规定的消息格式称作消息协议。
消息包括:
被请求的对象标识、被请求的服务标识、输入信息和应答信息。
如:
用电视遥控器发送一个选台消息,请求电视机执行换台服务。
6、结构与连接
一个系统一般由很多对象组成,对象之间并不是互相孤立的,而是存在着各种各样的关系。
包括:
部分/整体、一般/特殊、实例连接、消息连接。
(1)部分/整体
对象之间存在的部分与整体的结构关系。
如CPU是PC机的一个部分,PC机由CPU、内存、硬盘、显示器、键盘等组成。
部分/整体关系中有两种方式:
组合和聚合。
上面PC机就是一个组合的例子,一个部分对象(CPU)只能属于一个唯一的整体对象(PC机)。
组合关系中部分和整体的关系很紧密。
聚合关系中则比较松散,一个部分对象可以属于几个整体对象。
(2)一般/特殊
对象之间存在着一般和特殊的结构关系,也就是说它们存在继承关系。
很多时候也称作泛化和特化关系。
(3)实例连接
实例连接表现了对象之间的静态联系,它通过对象的属性来表现出对象之间的依赖关系。
对象之间的实例连接称作链接,对象类之间的实例连接称作关联
(4)消息连接
消息连接表现了对象之间的动态联系,它表现了这样一种联系:
一个对象发送消息请求另一个对象的服务,接收消息的对象响应消息,执行相应的服务。
7、多态性
多态性是指一般类中定义的属性和服务,在特殊类中不改变其名字,但通过各自不同的实现后,可以具有不同的数据类型或具有不同的行为。
如一个绘图系统中类的多态性:
当向图形对象发送消息进行绘图服务请求后,图形对象会自动判断自己的所属类然后执行相应的绘图服务。
1.3UML概述
既然面向对象是一种思维方式,当然就需要用一种语言来表达、来交流。
UML就是表达面向对象的标准化语言。
UML只是语言,不是方法。
任何语言都有语法和语义两个方面。
UML采用元-元模型、元模型、模型和用户对象四个层次来定义其体系结构。
UML是基于面向对象的可视化建模语言,支持面向对象的各种概念,提供了丰富的概念元素和图形表示元素,就像英语语言中提供了丰富的单词。
通过用UML元素按照规定的语法建立系统模型,可以按照不同的抽象层次建立如分析模型和设计模型。
UML的公共机制包括:
说明、装饰、通用划分、扩展机制。
下一章我们将进一步讨论UML语言。
第二章、
UML语言
前面介绍了面向对象方法的概念。
下面介绍表达面向对象方法的有力工具:
UML语言。
2.1UML语言的体系结构
这四个层次中,除元-元模型外,每一层都是上一层的实例。
(1)元-元模型是定义描述元模型的语言,它是任何模型的基础。
(2)元模型是描述模型的语言。
在UML语言的元模型中,定义了面向对象范畴的概念,如:
对象类、关联、链接等。
(3)模型是对现实世界的抽象,用来描述信息领域,如:
银行系统中的储户、帐户等它们都是元模型中对象类的实例。
(4)用户对象是一个特定的信息领域对象,如:
张三(张三是储户对象类的一个实例)。
2.2符号与图形
在UML元模型中定义了很多模型元素,如:
UseCase、对象类、接口、组件等,为了模型的可视化,UML为每个模型元素规定的特定的图形符号来表示。
1、活动者(Actor)
活动者是作用于系统的一个角色或者说是一个外部用户。
活动者可以是一个人,也可以是使用本系统的外部系统。
2、用例(UseCase)
用例就是对活动者使用系统的一项功能的交互过程的陈述。
如:
用户进行登录的用例图可以表示为:
3、对象类(Class)
对象类(类)是具有相同属性和相同操作的对象的集合。
(1)属性(Attribute)
(2)操作(Operation)
如用户类:
4、接口(Interface)
接口是一种抽象类,它对外提供一组操作,但自己没有属性和方法(操作的实现),它是在没有给出对象实现的情况下对对象行为的描述。
接口使用对象类的图形表示方法,接口名前面加构造型《interface》。
5、组件(Component)
组件体现了系统中逻辑模型元素的物理实现。
6、包(Package)
包也是一种模型元素,可以把语义相近的模型元素组织在一个包里,增加对模型元素的可维护性。
7、节点(Node)
节点是表示计算机资源运行时的物理对象,一般指有处理能力的硬件设备。
节点上可以包含对象和组件的实例。
8、关联(Association)
关联就是类或对象之类链接的描述。
9、组合(Composition)
组合关系用于表示对象之间部分和整体关系,关系很紧密。
10、聚合(Aggregation)
聚合关系也用于表示对象之间部分和整体关系,但关系比较松散。
11、泛化(Generalization)
泛化用于表示对象之间一般和特殊的结构关系。
12、依赖(Dependency)
依赖表示两个或多个模型元素之间语义上的关系。
13、实现(Realization)
实现是指一个模型元素(如:
类)是另一个模型元素(如:
接口)的实现。
14、消息(Message)
一般消息
返回消息
15、状态(State)
状态描述了对象在生命周期中的一个时间段。
16、注释(Comment)
注释没有特定的语义,它用于对其他模型元素的补充说明。
面向对象系统设计
当你阅读到这里时,我假设你已经理解了面向对象的基本概念,初步掌握了的UML语言。
第三章、架构设计
3.1架构设计原则
系统设计的第一步就是确定软件的架构,它决定了各子系统如何组织以及如何协调工作。
架构设计的好坏影响到软件的好坏,系统越大越是这样。
进行架构设计时,有两个重要的原则可以遵循:
一、分层。
将系统分层是简化系统的好方法,而且已经得到了很好的证实,如OSI七层模型网络协议,数据库管理系统的外模式、模式、内模式等。
分层的思路是将系统按功能职责进行划分,将同一类职责的功能抽象为一层。
在信息系统中软件架构通常采用典型的三层结构:
1、表示层――用户界面。
2、业务层――业务处理流程。
3、数据层――持久化存储。
与传统的两层结构相比,它最大的特征是将业务层独立了出来,从而提高了业务层的可复用性。
在两层结构中,用户界面和业务处理流程放在一起,因此无法直接复用业务处理的相关功能,也无法将业务处理功能进行灵活的部署。
在三层结构中,表示层只处理用户界面相关的功能,业务层专心处理业务流程,可以对业务层进行灵活的部署,开发时也便于业务处理的开发和用户界面的开发同时进行。
当然也可以分为更多的层,关键是尽量提高层内各功能的内聚,降低各层之间的耦合。
二、各层之间通讯。
OSI中要求高层只能调用它的下一层提供的接口,我们设计接口时也尽量遵守这样的约束,例如典型的三层结构的访问关系为:
数据层在业务层中是可见的,业务层在表示层中是可见的,反之则不可见。
为什么在业务层中不能直接访问表示层呢?
因为业务层要相对独立,它不能依赖于任何表示层,以至于一个业务层可以对应多个表示层。
业务层可以间接与表示层通讯,这种通讯方式根据实际需要来确定。
3.2信息系统的架构设计
下面我们将根据架构设计原则和信息系统原理来建立一个信息系统的架构设计模型。
将信息系统中比较关心的对象分层,可分为三层:
用户界面层、业务层、数据访问层,再把各层中的一些公共部分提出来:
权限管理、异常处理,这样得到包图如下:
3.2.1用户界面包
用户界面层的职责是:
1、与用户的交互,接收用户的各种输入以及输出各种提示信息或处理结果。
2、对于输入的数据进行数据校验,过滤非法数据。
3、向业务处理对象发送处理请求。
包含类:
3.2.2业务处理包
业务处理层的职责是:
1、实现各种业务处理逻辑或处理算法。
2、验证请求者的权限。
3、向数据访问对象发送数据持久化操作的请求。
4、向用户界面层返回处理结果。
包含类:
这里使用了代理(Proxy)模式,用户界面对象只能通过业务代理对象来向业务对象发送请求。
业务代理对象首先判断请求者的权限,然后转发合法请求者的请求。
3.2.3数据访问包
数据访问层的职责是:
1、实现数据的持久化操作(本书假设数据的存储由关系数据库来完成)。
2、实现事务处理。
包含类:
对于每一个业务处理中需要持久化操作的对象都可以对应为一个数据库访问对象,在很多业务处理中需要请求多个数据库访问对象来进行数据的读写操作,而这些操作又必须在同一个事务中,这时需要用同一个数据库连接对象来进行统一的事务处理。
这里的数据库连接类的创建用到了单件(Singleton)模式,保证一个类仅有一个实例,一个客户在同一时刻只能用一个数据库连接对象。
3.2.4权限管理包
权限管理的主要职责是:
1、验证请求者的请求权限。
2、提供请求者的权限列表。
包含类:
业务处理对象通过权限管理对象来验证权限。
3.2.5异常处理包
异常处理的职责:
1、汇报运行时的详细异常信息。
2、记录异常处理日志。
包含类:
因为异常处理类型比较多,如:
系统异常、数据库异常、业务逻辑异常等,针对不同类型的异常处理方式也容易变,如:
显示错误,记录文本日志,记录数据库日志等,所以这里使用了桥接(Bridge)模式来实现,使各部分的变化比较独立。
3.2.6架构的类图
将包图展开,得到类图,它是架构的静态结构图,表达了各个类之间的静态联系:
3.2.7架构的动态图
它是对象的动态结构图,表达了类对象之间的动态协助关系。
流程:
1、用户界面对象在接收了用户的输入请求后,向业务代理对象发送处理请求。
2、业务代理对象接收到请求后,向权限管理对象发送验证权限请求。
3、权限管理对象验证权限后将验证结果返回给业务代理对象。
4、业务代理对象根据验证结果进行以下处理:
对于不符合权限的请求则返回提示信息;对于符合权限的请求,则将请求转发给业务对象。
5、业务对象进行业务处理。
对于业务处理中的数据持久化操作,通过访问数据库访问对象进行操作,期间的任何异常都交给异常处理对象处理。
最后返回处理结果信息给业务代理对象。
6、业务代理对象将处理结果信息返回给用户界面。
至此,我们已经学习了架构设计原则,并建立了一个信息系统的架构设计模型。
下面我们将学习在系统设计中更为细化的“类设计”。
第四章、类设计
类设计的目的是在架构设计的基础上,将分析模型转换成程序设计语言可以实现的对象类和对象的静态、动态关系。
本章将通过建立“通用日记帐财务系统”来介绍类设计的过程和设计思路。
4.1类设计指南
⏹作为类设计的第一步是查找类,可以从分析模型中查找。
⏹优化类,对具有共同特征的类进行抽象,得出一个超类或接口。
⏹建立类之间的静态联系。
⏹建立类之间的动态联系。
⏹尽量符合设计原则(请参考《设计原则》一书)、尽量使用设计模式(请参考《设计模式》一书)。
4.2通用日记帐财务系统-系统分析模型
把系统分析模型放到类设计章节来介绍本来是不合理的,因为类设计中不应该包含系统分析模型。
我之所以要这么做是因为后面章节的需要,为了使例子具有连续性而不希望让大家感觉到类图从天而降。
注意,现在的任务是要开发一套通用日记帐财务系统。
4.2.1系统需要完成什么功能?
用例图中有
活动者(或角色):
会计、财务管理人员、系统管理员。
用例:
帐套管理、会计科目管理、系统管理、汇总原始凭证管理、日记帐管理、分类帐管理、往来户管理、报表。
4.2.2系统管理员操作流程
(1)在系统开始时,系统管理员需要创建一个新的帐套,然后设置好本帐套的会计科目;
(2)系统管理员要负责日常的数据备份工作,当系统运行出现异常需要数据恢复时,要负责数据恢复工作。
4.2.3会计操作流程
(1)会计负责创建和维护往来户;
(2)会计根据原始凭证创建汇总原始凭证;
(3)系统根据汇总原始凭证登日记帐;
(4)系统根据日记帐登总分类帐和明细分类帐;
(5)会计可以查询日记帐和分类帐。
4.2.4财务管理人员操作流程
财务管理人员月终打印会计报表。
4.3通用日记帐财务系统-类图
4.3.1查找类
从上面的系统分析模型可以找出类:
汇总原始凭证、日记帐、分类帐、会计科目、往来户。
汇总原始凭证有子类:
收款凭证、付款凭证、转帐凭证。
分类帐有子类:
总分类帐、明细分类帐。
往来户有子类:
应收往来户、应付往来户。
4.3.2查找各个类的方法
例如查找原始凭证有些什么方法:
逐步查找出各个类的方法后,将它们联系起来,静态结构如下:
目前,你对通用日记帐财务系统的架构设计、系统设计应该有了很清楚的了解。
下面我们来讨论系统的持久化设计。
第五章、数据库设计
关系型数据库是目前应用最广泛的数据库。
既然是面向对象系统设计,数据库设计当然也要是面向对象的。
现在要考虑如何对类进行持久化操作,即如何将对象类映射到关系数据库的二维表。
5.1映射原则
(1)基础类可以采用一类一表制或一类多表制的映射原则;
(2)当类之间有一对多关系时,一个表也可以对应多个类;
(3)存在继承关系的类可以映射为一个表,用属性来区别不同的子类,也可以是不同的子类分别映射一个表;
(4)类属性映射为表字段,类之间的关联也用表字段来表示;
(5)按关系数据库规范化原则来调整表结构。
5.2映射
(1)会计科目是一个基础类,可以直接映射为一个表;
(2)日记帐是一个记录变化过程的类,它与通用记帐凭证是一对一的关系,可以映射为一个表;
(3)原始汇总凭证、分类帐、往来户都存在着继承关系,可以分别对应一个表,也可以是它们和它们的子类分别对应一个表;
(4)架构设计中需要进行持久化操作的是操作员类和角色类。
5.3ER图