结构化分析将数据和处理作为分析对象,数据的分析结果表示了现实世界中实体的属性及其之间的相互关系,而处理的分析结果则展现了系统对数据的加工和转换。面向数据流建模是目前仍被广泛使用的方法之一,而DFD则是面向数据流建模中的重要工具,DFD将系统建模成输入-处理-输出的模型,即流入软件的数据对象,经由处理的转换,最后以结果数据对象的形式流出软件。DFD使用分层的方式表示,第一个数据流模型有时被称为0层DFD或环境数据流图。从整体上表现系统,随后的数据流图将改进第0层图,并增加细节信息。
除DFD外,在进行建模时,还可以结合数据字典和加工处理说明对DFD进行补充。数据字典以准确且无二义的方式定义所有被加工引用的数据流和数据存储,通常包括数据流条目、数据存储条目和数据项条目。数据流条目描述DFD中数据流的组成,数据存储条目描述DFD中数据存储文件的组成,而数据项条目描述数据流或数据存储中所使用的数据项。加工处理说明则可采用结构化自然语言、判定表和判定树等多种形式进行详细描述,其目的在于说明加工做什么。
掌握上述工具后,即可对问题进行结构化分析,其实施步骤如下。
在实际使用DFD进行数据流建模时需要注意以下原则。
DFD、数据字典和加工说明可以充分地描述系统的分析模型,其后需要对分析模型进行变换从而得到系统的总体设计模型。系统总体设计模型可以采用层次图、HIPO图和结构图来表达,但不论是哪一种图形工具,都反映了模块间的调用关系。
分析模型的基础上进行设计时,主要是针对DFD进行变换从而得到模块的调用关系图,因此,需要掌握数据流的变换设计和事务设计。面向数据流的设计方法把数据流图映射成软件结构,数据流图类型决定了映射的方法,数据流图可分为变换数据流图和事务数据流图。变换数据流图具有明显的输入、变换、输出;而事务型数据流图则是数据沿输入通路到达一个处理时,这个处理根据输入的类型在若干个动作序列中选择一个来执行。变换设计的核心在于确定输入流和输出流的边界,从而孤立出变换中心;事务设计的核心在于将事务类型判断处理变换成调度模块以选择后续的输出分支模块。
经过总体设计阶段的 工作,已经确定了软件的模块结构和接口描述,但每个模块仍被看做黑盒子。后续的详细设计目标是确定怎么样具体的实现所要求的系统,经过详细设计,可以得出对目标系统的精确描述,从而在编码阶段可以将这个描述直接翻译成某种程序设计语言书写的程序。因此,详细设计的结果基本上决定了最终程序代码的质量。详细设计可以采用程序流程图、N-S图、PAD图、PDL语言等工具来表达。下面通过一个案例来说明如何应用结构化分析、总体设计和详细设计技术。
图书管理系统的主要功能包括图书购入、借阅、归还以及注销。管理人员可以查询读者、图书的借阅情况,还可以对当前图书借阅情况进行统计,给出统计数据。简单的图书管理系统针对图书进行4个方面的管理:购入新书、读者借书、读者还书以及图书注销。
购入新书需要为该书编制图书卡片,包括分类目录号、流水号、书名、作者、内容摘要、价格和购书日期等信息,并将这些信息写入图书目录文件中。
读者借书时需要填写借书单,包括读者号、欲借图书分类目录号,系统首先检查该读者号是否有效,若无效,则拒绝借书;否则进一步检查该读者所借图书是否超过最大限制数。若已达到最大限制数,则拒绝借书;若未达到最大限制数,读者可以借书,登记图书分类目录号、读者号和借阅日期等,写回到借书文件中。
读者还书时,根据图书分类目录号,从借书文件中读出和该图书相关的借阅记录,标明还书日期,再写回借书文件中。如果图书逾期未还,则处以相应的缴罚。
在某些情况下,需要对图书馆的图书进行清理,对一些过时或无继续保留价值的图书要注销,这时从图书馆里删除相关记录。
查询要求分为查询读者信息、图书信息、借阅信息。
结构化分析的最终结果需要得到系统的数据流图、数据字典和加工说明。根据需求说明,首先界定系统的边界。因为购入新书、读者借书、读者还书和图书注销将来都是由图书管理员来操作系统,因此图书管理员将是系统的外部实体之一。当读者借书超期时,系统会给读者一个罚款单信息,所以,这里可以将系统时钟和读者也作为系统的外部实体之一。当然,如果认为罚款单是由管理员转交给读者,则可以认为图书管理系统只和 管理员、系统时钟
进行交互,这里采用第二种观点。查询要求同样都是由管理员来操作,由此可以得出系统不完整的第0层DFD数据流图。
在 0 层 DFD 图上分析外部实体与系统间的数据流,因为管理员的两大工作任务是分析管理任务和查询任务,因此管理员会向系统输入管理请求信息与查询请求信息,根据输入的管理请求,系统会将一些存储文件进行修改;对查询来说,系统则会给出读者、图书与借阅的统计信息。系统时钟主要为图书管理系统提供系统时间。下图为补充数据流所得完整的0层 DFD 数据流图。
随后对0层 DFD 数据流图中的图书管理系统进行进一步细化,根据需求得知,系统主要分为管理任务和查询任务,因此可以将其细化为两个大的处理。
同样,对处理2进行进一步细化,管理处理分为购书、借书、还书和清理4项任务,因此可以将处理2分解为4个处理。另外需要一个单独的处理器根据管理请求的类型进行请求分派。细化后的数据流图如下所示。
同样的方法,可对处理1进行细化。细化完成后,对得到的数据流图进行转化,从而形成系统的总体设计、但在转换之前,应对数据流图中的数据流采用数据字典进行详细说明,例如:
对于底层处理,以2.3为例进行说明。
由于数据流呈现了事务型的特性,因此可采用事务型的变换方式对数据流图进行变换,得到的系统总体结构图如下所示。
总体设计给出了数据流图中的各个处理转换为模块后模块与模块的调用关系,后续需要根据总体设计给出模块的详细设计。
以借书为例,采用程序流程图的形式描述借书模块的详细设计。分析借书的输入是读者信息和借书信息,需要地读者信息的借书证号,借书信息给出了读者已经借阅了多少本书,如果读者借阅的书籍数目尚未超出系统的限制,则允许借书,并把新的借书信息写入借书文件;否则,拒绝借书。该模块的详细流程如下所示。
完成每一个模块的详细设计,即可将详细设计转换为程序代码,从而实现整个管理系统。
数据库设计属于系统设计的范畴。通常把使用数据库的系统称为数据库应用系统,把对数据库应用系统的设计简称为数据库设计。数据库设计的任务是针对一个给定的应用环境,在给定的(或选择的)硬件环境和操作系统及数据库管理系统等软件环境下,创建一个性能良好的数据库模式,建立数据库及其应用系统,使之能有效的存储和管理数据,满足各类用户的需求。合理的数据库结构是数据库应用系统性能良好的基础和保证,但数据库的设计技术,还要有程序开发的实际经验,掌握软件工程的原理和方法。数据库设计人员必须深入应用环境,了解用户的具体专业业务。在数据库设计的前驱和后期,与应用单位人员密切联系,共同开发,可大大提高数据库设计的成功率。
1.数据库设计的策略
自顶向下(Top Down)
从一般到特殊的开发策略,它从一个企业的高层管理着手,分析企业的目标、对象和策略,构造抽象的高层数据模型。然后逐步构造越来越详细的描述和模型(子系统模型)。模型不断扩展细化,直到能识别特定的数据库及其应用为止。
自底向上(Bottom Up)
采用与抽象相反的顺序进行。它从各种基本业务和数据处理着手,即从一个企业的各个基层业务子系统的业务处理开始,进行分析和设计。然后将各个子系统进行综合和集中,进行上一层的分析和设计,不同的数据进行综合。最后得到整个信息系统的分析和设计。
这两种方法各有优缺点,在实际的数据库设计开发过程中,常常把这两种方法综合起来使用。
2.数据库设计的步骤
数据库设计分为以下4个主要阶段。
当各阶段发现不能满足用户需求时,均需返回到前面适当的阶段,进行必要的修正。如此经过不断地迭代和求精,直到各种性能均能满足用户需求为止。
需求分析是在项目确定之后,用户和设计人员对数据库应用系统所要设计的内容和功能的整理和描述,是以用户的角度来认识系统。这一过程是后续开发的基础,以后的逻辑设计和物理设计以及应用程序的设计都会以此为依据。
1.需求分析的任务、目标及方法
需求分析的任务:综合各个用户的应用需求,对现实世界要处理的对象(组织、部门和企业等)进行详细调查,了解现行系统的情况,确定新系统功能的过程中,收集支持系统目标的基础数据及处理方法。
参与需求分析的主要人员是分析人员和用户。这是由于数据库应用系统是面向企业和部门的具体业务,分析人员一般并不了解,而同样用户也不具有系统分析的能力,这就需要双方进行有效的沟通,使得设计人员对用户的各项业务了解和熟悉,进行分析和加工,将用户眼中的业务转换成为设计人员所需要的信息组织。
分析和表达用户需求的方法主要包括自顶向下和自底向上两类方法。自顶向下的结构化分析方法从最上面的系统组织机构入手,采用逐层分解的方式分析系统,并把每一层用数据流图和数据字典描述。需求分析的重点是调查组织机构情况、调查各部门的业务活动情况、协助用户明确对新系统的各种要求、确定新系统的边界,以此获得用户对系统的如下要求:
2.需求分析阶段的文档
需求调查所得到的的数据可能是零碎的、局部的,分析师和设计人员必须进一步分析和表达用户的需求,建立需求说明文档、数据字典和数据流图。将需求调查文档化,文档既要被用户所理解,又要方便数据库的概念结构设计。
数据流分析是对事务处理所需的原始数据的收集及经处理后所得的数据及其流向,一般用数据流图(DFD
)来表示。DFD
不仅指出了数据的流向,而且指出了需要进行的事务处理(但并不涉及如何处理,这是应用程序的设计范畴)。除了使用数据流图、数据字典以外,需求分析还可使用判定表、判定树等工具。下面介绍数据流图和数据字典,其他工具的使用可参见软件工程等方面的参考是。
数据字典是各类数据描述的集合,它是关于数据库中数据的描述,即元数据,而不是数据本身。如用户将向数据库中输入什么信息,从数据库中要得到什么信息,各类信息的内容和结构,信息之间的联系等。数据字典包括数据项、数据结构、数据流、数据存储和加工 5 个部分(至少应该包括每个字段的数据类型和每个表的主键和外键)。
需求分析阶段的成功是 系统需求说明书,主要包括数据流图、数据字典、各种说明性表格、统计输出表和系统功能结构图等。系统需求说明说是以后设计、开发、测试和验收等过程的重要依据。
数据库概念结构设计阶段是在需求分析的基础上,依照需求分析中的信息要求对用户信息加以分类、聚集和概括,建立信息模型,并依照选定的数据库管理系统软件转换称为数据的逻辑结构,再依照软/硬件环境,最终实现数据的合理存储,这一过程也称数据建模。
数据库概念结构设计的目的是产生反映系统信息需求的数据库概念结构,即概念模式。概念结构独立又支持数据库的 DBMS 和使用的硬件环境。此时,设计人员从用户的 角度看待数据以及数据处理的要求和约束,产生一个反映用户观点的概念模式,然后再把概念模式转换为逻辑模式。
1.概念结构设计策略与方法
概念结构设计是设计人员以用户的观点对用户信息的抽象和描述,从认知论的角度来将,它是从现实世界到信息世界的第一次抽象,不并考虑具体的数据库管理系统。
现实世界的事务纷繁复杂,即使是对某一具体的应用,由于存在大量不同的信息和对信息的各种处理,也必须加以分类整理,理清各类信息之间的关系,描述信息处理的流程,这一过程就是概念结构设计。
概念结构设计的策略通常有4种:
在实际应用中这些策略并没有严格的限定,可根据具体业务的特点选择。
2.用 E-R 方法建立概念模型
E-R 图的设计要依照上述的抽象机制,对需求分析阶段所得到的数据进行分类、聚集和概括,确定实体、属性和联系。概念结构的具体工具步骤包括选择局部应用、逐一设计分 E-R 图和 E-R 图合并,如下图所示。
选择局部应用。
需求分析阶段会得到大量的数据,这些数据分散杂乱,许多数据会应用于不同的处理,数据与数据之间关系也较为复杂,要最终确定实体、属性和联系,就必须根据数据流图这一线索清理数据。
数据流图是对业务处理过程从高层到低层的一级抽象,高层抽象流图一般反映系统的概貌,对数据的引用较为笼统,而底层又可能过于细致,不能体现数据的关联关系,因此要选择适当层次的数据流图,让这一层的每一部分对应一个局部应用,实现某一项功能。从这一层入手,就能很好的设计分 E-R 图。
逐一设计分 E-R 图。
划分好个各局部应用之后,就要对每一个局部应用注意设计分 E-R 图,又称局部 E-R 图。对于每一个局部应用,其所用到的数据都应该能收集在数据字典中,依照该局部应用的数据流图,从数据字典中提取出数据,使用抽象机制确定局部应用中的实体、实体的属性、实体标识符及实体间的联系及其类型。
事实上,在形成数据字典的过程中,数据结构、数据流和数据存储都是根据现实事务来确定的,因此都已经基本上对应了实体及其属性,以此为基础,加以适当的调整,增加联系及其类型,就可以设计分 E-R 图。
现实生活中,许多事物作为实体还是属性没有明确的界定,这需要根据具体情况而定,一般遵循以下两条准则。
E-R 图合并。
根据局部应用设计各局部 E-R 图之后,就可以对各分 E-R 图进行合并。合并的目的在于在合并过程中解决分 E-R 图中互相间存在的冲突,消除分 E-R 图之间存在的信息冗余,使之成为能够被全系统所有用户共同理解和接受的统一的、精炼的全局概念模型。合并的方法是指将具有相同实体的两个或多个 E-R 图合而为一,在合成后的 E-R 图中把相同实体用一个实体表示,合成后的实体的数学是所有分 E-R 图 中该实体的属性的并集,并以此实体为中心,并入其他所有分 E-R 图。再把合成后的 E-R 图以分 E-R 图看待,合并剩余的 E-R 图,直到所有的 E-R 图全部合并,构成一张全局 E-R 图。
分 E-R 图直接的冲突主要有以下三类:
分 E-R 图的合并过程中要对其进行优化,具体可从以下三个方面实现。
1:1
联系或 1:n
联系的实体可以予以合并,使实体个数减少,有利于减少将来数据库操作过程中的连接开销。逻辑结构设计是在概念结构设计的基础上进行数据模型设计,可以是层次模型、网状模型和关系模型,本节介绍如何在全局 E-R 图基础上进行关系模型的逻辑结构设计。逻辑结构设计阶段的主要工作步骤包括确定数据模型、将 E-R 图转换称为指定的数据模型、确定完整性约束和确定用户视图,如图所示。
1. E-R 图关系模式的转换
E-R 方法所得到的全局概念模型是对信息世界的描述,并不适用于计算机处理,为适合关系数据库系统的处理,必须将 E-R 图转换成关系模式。E-R 图是由实体、属性和联系三要素构成,而关系模式中只有唯一的结构——关系模式,即采用以下方法加以转换。
实体向关系模式的转换
将 E-R 图中的实体逐一转换称为一个关系,实体名对应关系模式的名称,实体属性转换成关系模式的数学,实体标识符就是关系的码(键)。
联系向关系模式的转换
E-R 图中的联系有3中:一对一联系(1:1
)、一对多联系(1:n
)和多对多联系(m:n
),针对这3中不同的联系,转换方法如下。
2.关系模式的规范化
由 E-R 图转换所得的初始关系模式并不一定能完全符合要求,还可能会有数据冗余、更新异常存在,这就需要经过进一步的规范化处理,具体步骤如下。
3NF
或 4NF
。3NF
、BCNF
或 4NF
.3.确定完整性约束
根据规范化理论确定了关系模式后,还要对关系模式加以约束,包括数据项的约束、表级约束及表间约束,可参照 SQL
标准来确定不同的约束,如检查约束、主码约束和参照完整性约束,以保证数据的正确性。
4.用户视图的确定
确定了整个系统的关系模式之后,还要根据数据流图及用户信息建立视图模式,提高数据的安全性和独立性。
数据库系统实现是离不开具体的计算机的,在实现数据库逻辑结构设计之后,就要确定数据库在计算机中的具体存储。数据库在物理设备上的存储结构与存取方法称为数据库的物理结构,它依赖于给定的计算机系统。为一个给定的逻辑数据模型设计一个最适合应用要求的物理结构的过程,就是数据库的物理设计。
在数据库的物理结构中,数据的基本单位是记录,记录是以文件的形式存储的,一条存储记录就对应这关系模式中的一条逻辑记录。在文件中还要存储记录的结构,如字段长度、记录长度等,增加必要的指针及存储特征的描述。
数据库的物理设计是离不开具体的 DBMS 的,不同 DBMS 对物理文件存取方式的支持不同,设计人员必须充分了解所用 DBMS 的内部特征,根据系统的处理要求和数据的特点来确定物理结构。数据库的物理设计工作过程如下图所示。
确定数据分布
从企业计算机应用环境触发,需要确定数据是集中管理还是分布式管理。
确定数据的存储结构
存储结构具体数据指数据文件中记录之间的物理结构。在文件中,数据是以记录为单位存储的,可以是顺序存储、哈希存储、堆存储、B+ 树存储等,要根据数据的处理要求和变更频度选定合理的物理结构。
为提高数据的访问速度,通常会采用索引技术。在物理设计阶段,要根据数据处理和修改要求,确定数据库文件的索引字段和索引类型。
确定数据的访问方式
数据的访问方式是由其存储结构所决定的,采用什么样的存储结构,就使用什么样的访问方式。数据库的物理结构主要由存储记录格式、记录在物理设备上的安排及访问路径(存取方法)等否成。
存储记录结构设计
存储记录结构包括记录的组成、数据项的类型、长度和数据项间的联系,以及逻辑记录到存储记录的映射。在设计记录的存储结构时,并不改变数据库的逻辑结构,但可以在物理上对记录进行分割。数据库中的数据项被的被访问频率不是很均匀,基本上符合公认的 “80/20 规则” ,即 “从数据库中检索的 80% 的数据格由其中的 20% 的数据项组成”。
当多个用户同时访问常用数据项时,会因访盘冲突而等待。如果将这些数据分布在不同的磁盘组上,当用户同时访问时,系统就可以并行地执行 I/O,减少访盘冲突,提高数据库的性能。所欲对于常用关系,最好将其水平分割成多个裂片,分布到多个磁盘组上,以均衡各个磁盘组的负荷,发挥多磁盘组并行操作的优势。
存储记录布局
存储记录的布局,就是确定数据的存放位置。存储记录可以作为一个整体,如何分布在物理区域上,是数据库物理结构设计重要的部分。聚簇功能可以大大提高按聚簇码进行查询的效率。聚簇功能不仅可用于单个关系,也适用于多个关系。设有职工表和部门表,其中部门号是两个表的公共属性。如果查询设计这两个表的连接操作,可以把部门号相同的职工元组和部门元组在物理上聚簇在一起,既可以显著提高连接速度,又可以节省存储空间。建立聚簇索引原则:
任何事务都有两面性,聚簇对于某些特定的应用可以明显提高性能,但对于与聚簇码无关的查询却毫无益处。相反地,当表中有数据插入、删除、修改时,关系中的有些元组就要被搬动后重新存储,建立聚簇索引的维护代价很大。
存取方法的设计
存取方法是为存储在物理设备上的数据提供存储和检索的能力。存取方法包括存储结构和检索机制两部分。存储结构限定了可能访问的路径和存储记录;检索机制定义每个应用的访问路径。
存取方法是快速存取数据库中数据的技术。数据库系统是多用户共享系统,对同一关系建立多条存取路径才能满足用户的多种应用要求。为关系建立多种存取路径是数据库物理设计的另一个任务,在数据库中建立存取路径最普遍的方法是建立索引。确定索引的一般顺序如下。
索引一般在数据库运行测试后,再加以调整。在 RDBMS
中,索引是改善存取路径的重要手段。使用索引的最大优点是可以减少检索的 CPU 服务时间和 I/O 服务时间,改善检索效率。但是不能对进行频繁存储操作的关系建立过多的索引,因为过多的索引会影响存储操作的性能。
在数据库正式投入运行之前,还需要完成很多工作。例如,在模式和子模式中加入数据库安全性、完整性描述,完成应用程序和加载程序的设计,数据库系统的试运行,并在试运行中对系统进行评价。如果评价不能满足要求,还要对数据库进行修正设计,直到满意为止。数据库正式投入使用,也并不意味这数据库设计生命周期结束,而是数据库维护阶段的开始。数据库实施的工作过程如下。
1.数据库的实施
根据逻辑和物理设计的结果再计算机上建立起实际的数据库结构并装入数据进行试运行和评价的过程叫做数据库的实施。
建立实际的数据结构
用 DBMS 提供的数据库定义语言(DDL
)编写描述逻辑结构设计和物理设计结果的程序,经计算机编译处理和执行后,就生成了实际的数据库结构。所用 DBMS 的产品不同,描述数据库结构的方式也不同。有的 DBMS 提供数据定义语言,有的提供数据库结构的图形化定义方式,有的两种方式都提供。在定义数据库结构时,应包含以下内容。
Tablespace
)、段(Segment
)、范围(Extent
)和数据库(Data block
)。DBA
或设计人员通过对数据库空间的管理和分配,可控制数据库中数据的磁盘分配,将确定的空间份额分配给数据库用户,控制数据的可用性,将数据存储在多个设备上,以提高数据库性能等。DDL
语句描述数据的完整性。数据的加载
数据库应用程序的设计应该与数据库设计同时进行。一般地,应用程序的设计应该包括数据库加载程序的设计。在数据加载前,必须对数据库进行整理。由于用户不了解数据的准确性对数据库系统正常运行的重要性,,因而未对提供的数据作严格的检查。所以,在数据加载前要建立严格的数据登录、输入、和校验规范,设计完善的数据校验与校正程序,排除不合格数据。
数据加载分手工输入和使用数据转换工具两种。现有的 DBMS 都提供了 DBMS 之间数据转换的工具。如果用户原来就使用数据库系统,可以利用新系统的数据转换工具。现将原系统中的表转换成新系统中相同结构的临时表,然后对临时表的数据进行处理后插入到相应表中。另外,由于还需要对数据库系统进行联合调试,所以大部分的数据加载工作应该在数据库的试运行和评价工作中分批进行。
数据库的试运行和评价
当加载了部分必须的数据和应用程序后,就可以开始对数据库系统进行联合调试,称为数据库的试运行。一般将数据库的试运行和评价结合起来,目的是测试应用程序的功能;测试数据库的运行效率是否达到设计目标,是否为用户所容忍。测试的目的是为了发现问题,而不是为了说明能达到哪些功能。因此,测试中一定要有非设计人员的参与。
2.数据库的维护
数据库实施完成后,才可以将系统交付使用。数据库一旦投入运行,就意味着数据库维护工作的开始。数据库维护工作的内容主要包括对数据库的监测和性能改善、故障恢复、数据库的重组和重构。在数据库运行阶段,对数据库的维护主要由 DBA
完成。
对数据库性能的检测和改善。
性能可以用处理一个事务的 I/O 量、CPU 时间和系统相应时间来度量。由于数据库应用环境、物理存储的变化,特别是用户和数据量的不断增加,数据库系统的运行性能会发生变化。某些数据结构经过一段时间的使用以后,可能会被破坏。所以,DBA
必须利用系统提供的性能监控和分析工具,经常对数据库的运行、存储空间及响应时间进行分析,结合用户的反应确定改进措施。目前的 DBMS 都提供一些系统监控和分析工具。
数据库的备份及故障恢复。
数据库重组和重构。
数据库运行一段时间后,由于记录的增、删、改,数据库中物理存储碎片记录链过多,影响了数据库的存取效率。这是,需要对数据库进行重组和部分重组。数据库的重组是指在不改变数据逻辑和物理结构的情况下去除数据库存储文件中的废弃空间以及碎片空间中的指针链,使数据库记录在物理上紧连。数据库的重构是指当数据库的逻辑结构不能满足当前数据处理的要求时,对数据库的模式和内模式修改。
注意:由于数据库重构的困难和复杂性,数据库的重构一般都在迫不得已的情况下才进行。例如,应用需求发生了变化,需要增加新的应用或实体,取消某些应用或实体。又如,表的增删、表中数据项的增删、数据项类型的变化等。重构数据库后,还需要修改相应的应用程序,并且重构也只能对部分数据库结构进行。一旦应用需求变化太大,需要对全部数据库结构进行重组,说明该数据库系统的生命周期已结束,需要设计新的数据库应用 系统。
某单位图书管需要建立一个图书管理系统,在图书管理过程中,由于要处理多种不同的业务流程,各个部门之间有相互联系。
1.图书馆理需求分析
通过对图书管理日常工作的详细调查,该图书馆对某书目的信息如下表所示。
书名 | 作者 | 出版商 | ISBN 号 |
出版年月 | 册数 | 经办人 |
---|---|---|---|---|---|---|
数据结构 | 严蔚敏 吴伟民 | 清华大学出版社 | ISBN7-302-02368-9 |
1997.4 | 4 | 01 |
该书目对应的图书信息如下表所示。
图书ID | ISBN号 | 存放位置 | 状态 | 经办人 |
---|---|---|---|---|
C832.1 |
ISBN7-302-02368-9 |
图书流通室 | 已借出 | 01 |
C832.2 |
ISBN7-302-02368-9 |
图书阅览室 | 不外借 | 01 |
C832.3 |
ISBN7-302-02368-9 |
图书流通室 | 未借出 | 01 |
C832.4 |
ISBN7-302-02368-9 |
图书流通室 | 已预约 | 01 |
初步的需求分析结果
CIP
,以下简称书目),书目的基本信息包括 ISBN
号、书名、作者、出版商、出版年月及本资料室拥有概述的册数、不同书目的ISBN
号不相同。ID
、ISBN
号、存放位置和当前状态,每一本书在系统中被赋予唯一的图书ID
。ID
、所借图书ID
、借阅时间和应还时间,读者还书时图书管理员在对应的借书信息中记录归还时间。ID
、需要借阅的图书的 ISBN
号和预约时间。业务流程
系统的主要业务处理如下。
ID
、书的ISBN
号、预约时间和预约期限(最长为10天)。一旦其他读者归还这种书,就自动通知该预约读者。系统将自动清楚超出预约期限的预约记录,并修改相关信息。ID
写入相应的预约登记录中(系统在清楚超出预约期限的记录时解除该图书的 “已预约” 状态);否则,将该图书的状态修改为 "未借出" 。2.图书管理概念结构设计
根据需求分析的结果设计的实体-联系图(不完整),如下图所示,请指出读者与图书、书目与读者、书目与图书之间的联系类型,并补充图中实体间缺少的联系。
联系类型
读者与图书、书目与读者、书目与图书之间的联系类型分析如下:
n:m
),即空(1)和空(2)应该分别填写 n 和 m。1:n
),即空(3)和空(4)应该分别填写 1 和 n。n:m
),即空(5)和空(6)应该分别填写 n 和 m。图书管理 E-R 模型
根据需求分析的结果,图书管理应该包括图书证注册、注销和挂失管理,因此在图中,管理员和读者实体间缺少的联系有注册、注销和挂失借书证管理联系。补充缺少的联系的 E-R 模型下图所示。
3.图书管理逻辑结构设计
根据概念设计得到的 E-R 图转换成图书管理系统的主要关系模式如下,请补充 “借还记录” 和 “预约登记” 关系中的空缺。注:时间格式为 “年.月.日 时:分:秒”,请指出读者、书目关系模式的主键,以及图书、借还记录和登记关系模式的主键和外键。
管理员(工号,姓名,权限)
读者(姓名,年龄,工作单位,借书证号,电话,Email)
书目( ISBN
号,书名,作者,出版商,出版年月,册数,工号)
图书(图书ID
,ISBN
号,存放位置,状态,工号)
借还记录(_ _(a) _ _,借出时间,应还时间,归还时间)
预约登记(_ _(b) _ _,预约时间,预约期限,图书ID
)
借书证管理(借书证号,使用状态,开始时间,结束时间,工号)
问题分析
由于读者借书时需由图书管理员登记借书证号、所借图书ID
、借出时间和应还时间,还书时图书管理员在对应的借书信息中记录归还时间,因此借还记录中的空(a)处应填入 “借书证号,图书ID
”。
读者对某书目进行预约登记时2,需记录借书证号、需要借阅的图书的 ISBN
号和预约时间等,目前的预约登记关系中已经有预约时间,预约期限,图书ID
,显然还需要记录是哪位读者预约了书,以及书的 ISBN
号,因此,预约登记关系模式中的空(b)处应填入 “借书证号, ISBN
号” 。
主键与外键
主键也成为你主码,是关系中的一个或一组属性,其值能唯一标识一个元组。根据图书管理的需求分析如下。
ISBN
号不同,书目关系的主键为数的 “ISBN
号”,外键是管理员关系的 “工号”。ISBN
号,因此所有的图书依据 "图书ID
" 互相区分,图书关系的主键是 "图书ID
" ,外键是书目关系的 “ISBN
号” 和管理员关系的 “工号”。ID
,借出时间”。借还记录是由联系借还对应的关系,它记录与图书和读者的联系。因此,借还记录具有外键为借书证号和图书ID
,分别与读者和图书相联。ISBN
号,预约时间”,外键是读者关系的 “借书证号”、书目关系的 “ISBN
号” 。在实现数据逻辑结构设计之后,就要确定数据库在计算机中的具体存储。由于数据库在物理设备上的存储结构与存取方法依赖于给定的计算机系统和应用环境,故案例中不再介绍。
面向对象开发方法将问题和问题的解决方案组织为离散对象的集合,数据结构和行为包含在对象的表示中。面向对象的特性包括表示、抽象、分类、封装、继承、多态和持久性。
面向对象开发方法包括面向对象分析、面向对象设计和面向对象实现。
Java
中的 Book
类。面向对象方法终分析和设计有时会存在一部分重叠,不是完全独立的活动。在迭代开发中,不严格区分分析、设计和实现,而是每次迭代不同程度地进行精化。
面向对象分析与设计目前采用最多的是使用 UML
。它是面向对象的标准建模语言,通过统一的语义和符号表示,使各种方法的建模过程和表示统一起来,已成为面向对象建模的工业标准。UML
通过事务、关系和图对现实世界进行建模。
面向对象分析包括3个活动:建模系统功能,发现并组织业务对象,组织对象并记录其关系。
面向对象设计的目的是说明系统的对象和消息,包括精化用例模型以及反映实现环境,建模支持用例情景的对象交互、行为和状态,修改对象模型以反映实现环境。
面向对象分析包以下关键步骤:
建模系统功能。需求分析包括对相关领域过程的描述,首先对系统需求进行建模,产生用例图。用例图促进并鼓励了用户参与,为后期测试、跟踪和维护等方面提供支持,是项目成功的一个关键因素。建模需求用例模型的目的是提取和分析足够的需求信息,准备一个模型,该模型表示用户需要什么。产生用例步骤如下:
然后建模用例活动,即建模系统的过程和步骤,描述业务过程或用例的活动的顺序流程和并行活动。UML
活动图用于构建系统的活动。建模用例执行过程中对象如何通过消息互相交互,将系统作为一个整体或几个子系统进行考虑。
定义领域模型。面向对象分析是从按对象分类的角度来创建对象领域的描述。领域的分解包括定义概念、属性和重要的关联。其结果可以被表示成领域模型,用一组显示领域概念或对象的图形来表示领域模型。
定义交互、行为和状态。面向对象设计定义软件及其协作。首先确定并分类用例设计类,然后确定类属性、行为和责任。交互概览图描述业务过程中的控制流概览,以及将多个图进行连接。序列图和通信图可描述场景中设计的所有对象类之间的交互。
定义设计类图。除了在交互图中表示对象协作的动态视图外,还可以使用设计类图来创建类定义的静态视图,并说明类的属性和方法。
下面通过一个案例来说明如何应用面向对象分析和设计技术。
某在线会议审稿系统主要处理会议前期的投稿和审稿事务。会议有名称、涵盖的主题(包括名称和描述)、提交期限、审稿期限、通知日期、状态和会议召开日期等信息。创建一个辛的会议后审稿系统启动,在审稿结束时关闭审稿过程。
用户在初始使用系统时,必须在系统中注册称为作者或审稿人,需要提供名称、单位、电子邮件、登录名、密码、登录的状态。
作者登录后提交稿件和浏览稿件审阅结果。提交稿件必须在提交时间范围内,其过程为输入标题和摘要,选择稿件所属主体类型、选择稿件所在位置(存储位置)。上述几步若未完成,则重复;若完成,则上传稿件至数据库存储中,系统发送接收到稿件的通知。稿件的信息包括稿件 ID
、标题、摘要、URL
、状态和录用标准。状态随着整个审稿过程的进行而进行更新。
审稿人登录后可设置感兴趣领域、审阅稿件给出评价以及罗列录用和拒绝的稿件。审阅意见从原创性、技术质量、相关性和总体评价多个方面进行输入。稿件要限制不能被作者本人审阅。
会议委员会主席是一个特殊审稿人,可以浏览提交的稿件、到了稿件提交的最终日期后给审稿人分配稿件、罗列录用或拒绝的稿件以及关闭审稿过程。如果审稿完成,浏览提交的稿件可以列出录用和拒绝的稿件。分配稿件时需要满足一篇稿件陆续被分配给3个审稿人审阅,当审阅完成时,如果3位审稿人的总体评价满足设定的录用标准(审稿人评价值大于等于某个阈值),则稿件被录用,否则退稿,并发送电子邮件通知作者被录用或退稿。如果稿件被录用,则准备打印版并打印。关闭审稿过程包括罗列录用和拒绝的稿件。
用例图描述系统与外部系统和用户的交互。换句话说,它们以图形化的方式描述了谁将使用系统,以及用户期望以什么方式与系统交互。用例也用于以文本化的方式描述每个交互的步骤。用例是一个行为上相关的步骤序列(场景),既可以是自动的也可以是手动的,其目的是完成一个业务任务。用例从外部用户的观点并以他们可以理解的方式和词汇描述系统功能。参与者代表了需要同系统交互交换信息的任何事务 。发起或触发用例的外部用户称为参与者,如人、组织、其他系统、外部设备甚至是时间。
初步需求分析得出参与者和用例,如下表所示。
参与者
参与者 | 说明 |
---|---|
User |
用户 |
Reviewer |
审稿人 |
Author |
作者 |
PCChair |
委员会主席 |
用例
名称 | 说明 |
---|---|
login |
登录系统 |
submit paper |
提交稿件 |
close reviewing process |
关闭审稿过程 |
set preferences |
设定兴趣领域 |
list accepted/rejected papers |
罗列录用或拒绝的稿件 |
register |
注册 |
browse reviewe results |
浏览稿件审阅结果 |
assign paper to reviewer |
分配稿件给审稿人 |
enter reviewe |
审阅稿件给出意见 |
browse submitted papers |
浏览提交的稿件 |
从需求说明中可知:
根据上述分析,建模下图所示的审稿系统用例图。
用例建模技术用于描述系统使用的模型,其建模过程是以用户为中心的建模过程,先识别问题中的参与者,在根据参与者确定每个参与者的用例、定义用例之间的关系、确定模型的过程。利用模型作为后续面向对象分析和设计的基础。
注意:要小心选用用例之间的关系,一般来说,这些关系都会增加用例和关系的个数。从而增加用例模型的复杂度。
在用例建模完成后,对每个用例进行细化,建模活动图。活动图描述一个业务过程或者一个用例的活动顺序,也可以用于系统的建模逻辑。在此以用例提交稿件(submit paper
)为例,建模其活动。
根据需求描述,提交稿件过程识别出下表所示的活动。
名称 | 说明 |
---|---|
select paper location |
选择稿件位置 |
select subject group |
选择主题类型 |
enter title and abstract |
输入标题和摘要 |
upload paper |
上传稿件 |
send notification |
发送通知 |
从建模用例图时可知,参与者、作者和用户之间存在继承关系,提交稿件和登录之间存在扩展关系,提交稿件必须是在登录之后执行,所以在提交稿件的过程中首先判断用户是否登录,如果登录则继续;如果没有登录,则执行登录活动。根据活动说明,建模出下图所示的活动图,其中《datastore
》用于说明稿件存储对象。
活动图不同于流程图,它提供了描述并行活动的机制,特别适用于建模操作正在执行时的活动以及哪些活动的结果。建模活动图时应遵循以下指导原则。
类图用于描述系统的对象结构,显示了构成系统的对象及其之间的关系。根据需求描述识别出对象类型有会议、用户、会议主题、稿件和审阅意见。
URL
、状态及审阅结果,并在系统内有唯一标识,所以稿件的属性有稿件 ID
、标题、摘要、URL
和审阅结果;行为有上传、分配和更新状态。类机器属性名称如下表所示。
对于类型之间,确定其对象/类关系、多重度以及角色名称,例如会议和稿件之间的关系是聚合关系,一个会议有很多稿件,用户分为普通 user、author 和 reviewer 三种角色,并对其中的约束条件加以说明,某一稿件的审阅人不可以是本稿的作者;reviewer.intersection(authors)->isEmpty
,得到图 12-17 所示的审稿系统的类图。
如果一个概念满足以下几点就应该抽象为一个类。
对象状态表示对象在其生命周期中某一点所处的条件,通过修改对象属性的一个后多个值的事件触发对象状态变化。状态图用于建模生命周期中事件如何改变对象可以经历的各种状态,以及引起对象从一个状态到另一个状态转换的事件。
基于需求描述中的信息,稿件上传成功之后,称为已上传状态。上传稿件的最后期限到了之后,就进入分配中,当分配给审稿人达到规定的3个之后,进入审阅中,审阅结束后,评估结果如果等于等于设定的阈值,则变为录用状态,然后发送 Email 之后,变为已通知,当提交完准备好印制的电子版时,进入打印中,打印之后,状态结束;如果评估结果小于设定的阈值,变为拒绝状态,发送给作者 Email 通知状态结束。根据分析,确定下表所示状态名称以及行为或事件涉及术语对照表。
状态名称 | 状态说明 | 事件或行为名称 | 事件或行为说明 |
---|---|---|---|
submitted | 已上传 | date=deadline | 日期到最后期限 |
under assignment | 分配中 | #reviewers | 审阅人数 |
under review | 审阅中 | evaluated | 审阅结果 |
accepted | 录用 | threshold | 阈值 |
rejected | 拒绝 | camera-ready submitted | 提交了印制的电子版 |
notified | 已通知 | published | 已印制 |
inPrint | 打印中 | send email | 发生 Email |
建模得到下图所示的一份稿件状态图。
在建模状态图时应该注意遵循以下指导原则。
状态名称要简单但具有描述性。
避免 “黑洞” 状态,即只有变换进来而没有任何转换发出的状态,这种状态要么由于该状态是一个最终状态,要么就是以及错过了一个或多个转换。
避免 “奇迹” 状态,即只有转变发出而没有任何转换进来的状态,这种状态要么是一个起点,要么就是已经错过一个或多个转换。
对于复合状态,需要对子状态集进行建模。
对于复杂的实体创建分层的状态图。
交互概览图是活动图的变体,描述业务过程中的控制流概览,软件过程中的详细逻辑概览,以及多个图进行连接,抽象掉了消息和生命线。审稿系统中显示一篇已分配的稿件(Displaying as assigned papers),首先获取(Retrieve list of assigned papers),然后再显示(Display selected paper),如下图所示。
序列图是以图形化的方式描述了在一个用例或操作的执行过程中对象如何通过消息互相交互,说明了消息在对象之间被发送和接收以及发送的顺序。根据分析设计的迭代演化需求,最初可以绘制系统序列图。系统序列图是一副描述角色和系统在用例场景下交互的图像,有助于确定进入和退出系统的高层信息。
审稿人获取已分配给自己的稿件的执行序列,浏览会议主页,看到主页后,从导航条浏览分配给自己的稿件,可循环进行选择,创建已分配稿件并显示给审稿人。涉及到的对象名称和执行步骤如下表所示。
对象名称 | 对象说明 | 操作名称 | 操作说明 |
---|---|---|---|
Reviewer |
审阅人 | navigate |
导航 |
ConferenceHomepage |
会议主页 | show |
显示 |
NavigationBar |
导航栏 | browse |
浏览 |
AssignedPapers |
分配的稿件 | select |
选择 |
Paper |
稿件 | create |
创建 |
ListOfAssignedPapers |
分配的稿件列表 |
建模序列图应该遵循以下指导原则。
算法理论的研究主要包括孙发设计技术和算法分析技术,这两者是不可分割的一个整体。算法设计要提出针对问题的高质量的算法,算法分析的对象是被提出的算法,并研究算法所耗费的计算资源与问题规模之间的函数关系,而每一个被设计出的算法只有经过算法分析才能评价其质量的优劣。
因此用什么方法来设计算法,如何判定一个算法的优劣,所设计的算法需要占用多少时间和空间资源,在实现一个软件系统时都是必须予以解决的重要问题。
12.4.2.1 算法设计过程
在设计算法时,需要考虑到几个问题:如何设计算法?如何表示算法?如何证明问题解决的正确性?如何评估算法的效率?如何进行算法的最优化?根据这些问题,可以归纳出算法设计的主要步骤:理解问题;确定相关因素,包括问题的输入与输出、用何种数据结构、用什么样的算法设计策略等;设计算法;证明所设计的算法的正确性;分析所设计的算法的效率;实现所设计的算法。
1)理解问题
在面对一个算法任务时,算法设计者往往不能准确地理解要求他做的是什么。对算法希望实现什么只有一个大致的想法就匆忙的落笔写算法,其后果往往是写出的算法漏洞百出。在设计算法时需要做的第一件事情就是完全理解要解决的问题,仔细月底问题的描述,手工处理一些小例子。
对于设计算法来说,这是一项重要的技能。准确地理解算法的输入是什么?要求算法做的是什么?即明确算法的入口和出口,这是设计算法的切入点。
2)确定相关因素
预测所有可能的输入
s废的输入确定了该算法所解问题的一个实例。一般而言,对于问题P,总有其响应的实例集 I ,因此算法 A 若是问题 P 的算法,则意味着把 P 的任一实例 input ∈ I 作为算法A的输入,都能得到问题 P 的正确输出。
预测算法所有可能的输入,包括合法的输入和非法的输入。事实上,无法保证一个算法(或程序)永远都不会遇到一个错误的输入,一个对大部分输入都运行正确而只有一个输入不行的算法,就像一颗等待爆炸的炸弹。这绝不是危言耸听,有大量这种引起灾难性后果的案例。
如果养成习惯——首先考虑问题和它的数据,然后列举出算法必须处理的所有特殊情况,那么可以更快速地成功构造算法。
在精确解和近似解间做选择。
计算机科学的研究目的是用计算机来求解人类所面临的各种问题。但是,有些问题无法求得精确解。例如求平方根、解非线性方程和求定积分等。有些问题由于其固有的复杂性,求精确解需要花费太长时间,其中最著名的要算旅行商问题(TSP问题),此时,只能求出近似解。
确定适当的数据结构。
算法+数据结构=程序。
很多情况下,数据结构设计直接影响算法的时间性能。
确定算法设计技术。
分治法、动态规划法、贪心算法、回溯法、分支界限法、概率算法和近似算法等,已经被证明是对算法设计非常有用的通用技术,他们构成了一组强有力的工具,在为新问题设计算法时,可以运用这些技术设计出新的算法。算法设计作为问题求解的一般性策略,在解决计算机领域意外的问题时,也能发挥相当大的作用。
3)设计算法
根据 1) 和 2) 的结果,就可以设计算法。必须清楚、准确地将所设计的求解步骤记录下来,即描述算法。描述算法的常用方法有自然语言、流程图、程序设计语言和伪代码等。其中,伪代码是比较合适的描述算法的方法。
4)证明算法的正确性
可以用循环不变式来证明算法的正确性,以插入排序为例介绍循环不变式,以下是插入排序的C代码。
void insertSort(int data[], int n) {
/**用直接插入排序法将data[0]~data[n-1]中的n个整数进行升序排列*/
int i,j; int tmp;
for(i=1; i=0&&data[j]>tmp; j--)//查找插入位置并将元素后移
data[j+1]=data[j];
data[j+1]=tmp;//插入正确位置
}
}
}
对于要分析的算法,定义循环不变式,如对插入排序,定义其外层循环的循环不变式为:在每一论迭代的开始,子数组A[1....j-1]中包含了最初位于 A[1...j-1],但目前已经拍好的各个元素,然后证明循环不变式的3个性质。
初始化
在循环的第一轮迭代开始之前,它是正确的。对于插入排序,在第一轮迭代之前,j=2,子数组为 A[1....j-1] ,即 A[1] ,也就是最初在 A[1] 中的那个元素,显然这个子数组是已排好序的,因此循环不变式成立。
保持
如果在循环的每一次迭代之前它是正确的,那么在下一次迭代之前,它也应该保持正确。对于插入排序(上述伪代码包含两重循环,应该定义两个循环不变式,并证明它们是正确的。但为了简便,暂时不陷入过于形式化的细节,仅考虑外层循环),要将 A[j-1]、A[j-2]、A[j-3]等元素向右移一个位置,直到找到 A[j]的适当位置为止,这是将 A[j] 的值插入。很显然,循环不变式是成立的。
终止
当循环结束时,循环不变式给了我们一个有用的性质,它有助于表名算法是正确的。对于插入排序,当 j 大于 n 时,外层 for 循环结束。在循环不变式中,将j替换为 n+1 ,就有子数组 A[1...n]包含了原先在A[1...n]中的元素,但现在已经安排好了,这意味着算法是正确的。
除了循环不变式外,经验和研究表名,发现算法中逻辑错误的重要方法就是系统地跟踪算法。跟踪必须要用“心和手“来进行,跟踪这要像计算机一样,用一组输入值来执行该算法,并且这组输入值要最大可能得暴露算法中的错误。即使有几十年经验的高级软件工程师也经常利用此方法查找算法中的逻辑错误。
5)分析算法的效率
设计出的算法只有经过分析,才能评价其优劣,才能判断能否满足问题求解的需求或者在多个算法之间进行选择。算法分析主要分析两种效率:时间效率和空间效率。一般来说,更关注时间效率。
6)根据算法编写代码
12.4.2.2 算法问题类型
1)查找问题
查找是一个数据集合中查找给定条件的记录。对于查找问题来说没有一种算法对于任何情况是适合的。有的算法比较快,但却需要较多的存储空间(例如Hash查找);有的算法查找速度非常快,但仅适用于有序数组(例如折半查找),等等。此外,如果在查找过程中数据集合可能频繁地发送变化,除了考虑查找操作外,还需要考虑在数据集合中执行插入和删除等操作。这种情况下,就必须仔细地设计数据结构和算法,以便在各种操作的需求之间达到一个平衡。而且,组织用于高效查找的特大型数据集合对于实际应用具有非常重要的意义。
2)排序问题
简单地说,排序就是将一个记录的无需序列调整为一个有序序列的过程。在对记录进行排序时,需要选定一个信息作为排序的依据,这个信息称为“关键码”。排序的目的就是为了进行快速查找,这就是为什么字典、电话薄和班级名册都是排好序的。当然,在很多领域的重要算法中,排序也被作为一个辅助步骤,例如,搜索引擎将搜索到的结果按相关程度排序后显示给用户。
3)图问题
4)组合问题
组合问题一般都是最优化问题。组合问题是计算领域中最难的问题,其原因如下:
5)几何问题
面向对象程序设计主要是根据问题的详细描述,设计出能够被迅速转换为面向对象的程序实现的代码,相比本章的第 12.3 节,其设计与实现更为底层,更接近代码。但是,对面向对象设计结果的衡量没有统一的标准,因此很难对一个问题所设计的解决方案是否最优,这也是软件工程领域内分析与设计的难点,在更多的情况下,分析与设计的结果是一种经验总结。
尽管不存在一致的对分析与设计结果的衡量标准,但许多面向对象和软件工程领域内的 “大师” 都根据自己长期的实践经验总结出了面向对象分析与设计的原则,而这些原则可称为我们在对实际问题进行分析与设计时的指导准则。
一般而言,当面临一个具体的问题时,可分为两大阶段:首先根据问题进行设计,其次根据设计进行实现。由于面向对象的实现和面向对象设计之间不存在较大的差异,所不同的是设计更多采用的是 UML
的标准表示,而实现则是采用面向对象语言表达,因此解决问题的重点应放在面向对象的设计上。
目前,被公认的好的面向对象设计是由前任所总结的设计模式。因此,熟练并正确掌握面向对象设计技术,必须很好地体会并理解常用的 23 种设计模式。在对 23 种设计模式加以运用时,必须做到以下几点:
下面通过具体的应用来说明这个过程。
1.问题说明
已知某类库开发商提供了一套类库,类库中另一了 Application 类和 Document 类,他们之间的关系如图所示。
2.根据设计名称画出其对应的类图
3.理解类图中每一个类的作用与功能
4.能够将现实问题中所描述的各种职责映射到类图中具体的类
5.能够使用一种面向对象语言实现设计