软件架构之系统分析与设计方法(1)

第 8 章:系统分析与设计方法

    对于架构设计师而言,如何进行系统设计是其“看家本领”,而设计是在对系统进行分析的基础上进行的,否则,设计就是“无米之炊”。从软件开发项目中的角色分配来看,系统架构设计师应该在信息系统项目管理师的协调下,与系统分析师协同工作。

8.1 定义问题与归结模型

    软件系统的目的是为了解决问题,因此在建模之初最重要的步骤是对问题的分析与定义,并在此基础上归结模型,这样才能够获得切实有效的模型。定义问题的过程包括:理解真实世界中的问题和用户的需要,并提出满足这些需要的解决方案的过程。

8.1.1 问题分析

    问题分析的目标就是在开发之前对要解决的问题有一个更透彻的理解。为了达到这一目标,通常需要经过在问题定义上达成共识,理解问题的本质,确定项目干系人和用户,定义系统的边界和确定系统实现的约束这五个步骤。

1.在问题定义上达成共识
     要检验大家是否在问题的定义上达成了共识,最简单的方法就是把问题写出来,看看是否能够获得大家的认可。而要使得这个过程更加有效,应该将问题用标准化的格式写出来,根据 UP 的建议,应该包括以下几个方面的要素。
问题概述:用简短的几句话,将所理解的问题本质描述出来;

  • 影响:说明该问题将会对哪些项目干系人(Stakeholder,风险承担者)产生影响;
  • 结果:确定问题对项目干系人和商业活动会产生什么样的影响;
  • 优点:概要性地提出解决方案,并列举出该解决方案的主要优点。

    在问题定义上达成共识,就能够有效地将开发团队的理解与用户的需求达成一致,这样就能够使得整个系统的开发沿着合理的方向发展。

2.理解问题的本质
    每一句描述都会夹杂着叙述者的个人理解和判断,因此透过表面深入本质,理解问题背后的问题,是问题分析阶段一个十分关键的任务。其中一种技术是“根本原因”分析,这是一种提示问题或其表象的根本原因的系统化方法。在实际的应用中,常使用因果鱼骨图和帕累托图两种方法。

(1)因果鱼骨图。因果鱼骨图是一种有效的探寻问题根源的技术,它通过直观的图形找出问题或现象的所有潜在原因,从而追踪出问题的根源。它能够帮助人们将问题的原因而放在首位,提供了一种运用集体智慧解决问题的方法。在使用时,通常按照以下步骤进行。

将问题简明扼要地写在右边的方框里;
确定问题潜在原因的主要类别,将它们连到鱼的脊骨上;
用头脑风暴法寻找原因并归类。图 8-1 是鱼骨图的一个示例。
在这里插入图片描述
(2)帕累托图。
    帕累托图是采用直方图的形式,根据问题的相对频率或大小从高往低降序排列,帮助设计师将精力集中在重要的问题上。它为 80%的问题找到关键的 20%的原因,它可以一目了然地显示出各个问题的相对重要程度,有助于预防在解决了一些问题后,却使另外一些问题变得更糟的现象发生。在使用时,通常按照以下步骤进行。

  • 明确问题:也就是前面达成共识的问题定义;
  • 找出问题的各种可能原因:通常可以利用头脑风暴来收集意见,并通过参考以往积累的资料和运营的数据来综合分析;
  • 选择评价标准和考察期限:最常用的评价标准包括频率(占总原因的百分比)和费用(产生的影响),而考察的期限则应具有相应问题的代表性,并不是越长越好;
  • 收集各种原因发生的频率及费用数据;
  • 将原因按照发生的频率或费用从大到小排列起来;
  • 将原因排在横轴上,频率或费用排列在纵轴上,形成如图 8-2 所示的结果。这样就能够将造成问题的关键原因捕获出来,以便指导设计出更符合需要、更能够解决问题的解决方案。
    在这里插入图片描述
    3.确定项目干系人和用户
        要想有效地解决问题,必须了解用户和其他相关的项目干系人(任何将从新系统或应用的实现中受到实质性影响的人)的需要。不同的项目干系人通常对问题有不同的看法和不同的需要,这些在解决问题时必须加以考虑。事实上,许多项目干系人就是系统的用户,这一部分通常是易于识别的;但还有一部分项目干系人是系统的间接用户,甚至只是受系统影响的商业结果,这一部分不易识别,但十分重要。

    在寻找项目干系人时,可以思考:系统的用户是谁?系统的客户(购买者)是谁?还有哪些人会受到系统输出的影响?系统完成并投入使用后,有谁会对它进行评估?还有没有其他系统内部或外部的客户,他们的需要有没有必要去考虑?系统将来由谁来维护?

4.定义系统的边界
    系统的边界是指解决方案系统和现实世界之间的边界。在系统边界中,信息以输入和输出的形式流入系统并由系统流向系统外的用户,所有和系统的交互都是通过系统和外界的接口进行的。在定义系统的边界时,将世界分为两个部分:系统及与系统进行交互的事物。要描述系统的边界有两种方法:一种是结构化分析中的“上下文范围图”,另一种则是面向对象分析中的“用例模型”。

(1)上下文范围图。也就是数据流图中的顶层图,它是一个反映领域信息的模型,能够清晰地显示出系统的工作职责和相邻系统的职责起止之处,从而让读者能够从宏观的层面去了解系统。图 8-3 就是一个描述“证券经纪人系统”的上下文范围图。

(2)用例模型。用例模型则通过引入参与者来描述“和系统进行交互的事物”,只要识别了参与者,自然而然系统的界限就确定下来了。在寻找参与者时,可以思考以下问题:谁会对系统提供信息?谁会在系统中使用信息?谁会从系统中删除信息?谁将操作系统?系统将会在哪里被使用?系统从哪里得到信息?哪些外部系统要和系统进行交互?

    然后,再根据每个参与者的功能需求,识别出代表系统功能的用例,从而界定系统的边界。而关于用例模型的更多细节,请参考 8.4.3 节。
在这里插入图片描述
5.确定系统实现的约束
    由于各种因素的存在,会对解决方案的选择造成一定的限制,称这种限制为约束。每条约束都将影响到最后的解决方案的形成,甚至会影响是否能够提出解决方案。在考虑约束时,首先应该考察到不同的约束源,其中包括进度、投资收益、人员、设备预算、环境、操作系统、数据库、主机和客户机系统、技术问题、行政问题、已有软件、公司总体战略和程序、工具和语言的选择、人员及其他资源限制等。

8.1.2 问题定义

    通过对问题进行细致周密的分析,就可以对其进行综合的定义。对于一个问题的完整定义,通常应包括目标、功能需求和非功能需求三个方面。

1.目标
    目标是指构建系统的原因,它是最高层次的用户需求,是业务上的需要,而功能、性能需求则必须是以某种形式对该目标做出贡献。在描述目标时,应该注意以下几个方面。

  • 优势:目标应该不仅仅是解决问题,还要提供业务上的优势;
  • 度量:不仅要说明业务的优势,而且还必须提供度量这种优势的标准;
  • 合理性:要确保完成解决方案所需的工作量少于所获得的业务优势,这才是合理的解决方案;
  • 可行性:要探寻能够满足度量标准的解决方案;
  • 可达成性:对于组织而言,是否具备获取该系统的技能,构建完成后是否能够操作它。

例如,表 8-1 就是一个很好的目标描述的例子。
在这里插入图片描述
2.功能需求
    功能需求是用来指明系统必须做的事情,只有这些行为的存在,才有系统存在的价值。功能需求应该源于业务需求,它只与问题域相关,与解决方案域无关。也就是说,功能需求是在与用户或某个业务人员交谈时,他们所描述的内容是为了完成他们某部分的工作而必须做的事情。而在设计解决方案时,会遇到一些限制条件,这些东西也是“系统需求” 的一部分,不过应该是设计约束或非功能需求形式指定。

     在规定功能需求时要注意其详细程度。由于这些需求是业务需求,因此应该由业务人员来验证。也就是说,用户应该能够指明系统要达到有用的程度,功能是否已经足够;考虑到工作的成果,它的功能是否正确。另外,在描述功能需求时,应该注意需求的二义性。而二义性主要体现在以下几个方面。

(1)同名异义的词:在自然语言中存在许多同名但异义的词语,应该谨慎地排除它们带来的影响。

(2)代词:在需求描述中,代词经常会产生指代不明的现象,应该尽量避免使用,而是换成主语及宾语。

3.非功能需求
    非功能需求是系统必须具备的属性,这些属性可以看作是一些使产品具有吸引力、易用、快速或可靠的特征或属性。非功能需求并不改变产品的功能,它是为工作赋予特征的。在识别功能需求和非功能需求时,有一种十分有用的思维模式:功能需求是以动词为特征的,而非功能性需求则是以副词为特征的。非功能需求主要包括以下几种。

(1)观感需求:即产品外观的精神实质,也就是与用户界面的观感相关的一组属性;

(2)易用性需求:也就是产品的易用性程度,以及特殊的可用性考虑,通常包括用户的接受率、因为引入该产品而提高的生产效率、错误率、特殊人群的可用性等指标;

(3)性能需求:也就是关于功能实现要求有多快、多可靠、多少处理量及多精确的约束。例如:速度、精度、安全性、容量、值范围、吞吐量、资源使用效率、可靠性(平均无故障时间)、可用性(不停机时间)、可扩展性等;

(4)可操作性需求:衡量产品的操作环境,以及对该操作环境必须考虑的问题;

(5)可维护性和可移植性需求:期望的改变,以及完成改变允许的时间;

(6)安全性需求:产品的安全保密性,通常体现为保密性、完整性和可获得性;

(7)文化和政策需求:由产品的开发者和使用者所带来的特别需求;

(8)法律需求:哪些法律和标准适用于本产品。

8.2需求分析与软件设计

    需求分析是软件生命周期中相当重要的一个阶段。根据 Standish Group 对 23000 个项目进行的研究结果表明,28%的项目彻底失败,46%的项目超出经费预算或者超出工期,只有约 26%的项目获得成功。需求分析工作在整个软件开发生命周期中有着十分重要的意义。而在这些高达 74%的不成功项目中,有约 60%的失败是源于需求问题,也就是差不多有一半的项目都遇到了这个问题,这一可怕的现象引起人们对需求分析的高度重视。需求分析阶段的主要任务是通过开发人员与用户之间的广泛交流,不断澄清一些模糊的概念,最终形成一个完整的、清晰的、一致的需求说明。

    而当明确了用户的需求之后,下一步的任务就是对未来的软件系统进行设计,它是确定系统实现的关键工作。需求分析和设计的方法对软件开发过程而言是十分重要的,因此必须扎实地掌握它。

    需求分析与软件设计是软件生存期中最重要的两个步骤,需求分析解决的是“做什么”的问题,系统设计则是解决“怎么做”的问题。

8.2.1 需求分析的任务与过程

     需求分析所要做的工作是深入描述软件的功能和性能,确定软件设计的限制和软件同其他系统元素的接口细节,定义软件的其他有效性需求,细化软件要处理的数据域。用一句话概括就是:需求分析主要是确定待开发软件的功能、性能、数据、界面等要求。需求分析的

    实现步骤通常包括:获取当前系统的物理模型,抽象出当前系统的逻辑模型,建立目标系统的逻辑模型三个部分。具体来说,需求分析阶段的工作可以分成 4 个方面:

(1)问题识别:用于发现需求、描述需求,主要包括功能需求、性能需求、环境需求、可靠性需求、安全保密需求、用户界面需求、资源使用需求、软件成本消耗与开发进度需求,以此来预先估计以后系统可能达到的目标。

(2)分析与综合:也就是对问题进行分析,然后在此基础上整合出解决方案。这个步骤经常是反复进行的,常用的方法有面向数据流的结构化分析方法(Structured Analysis,SA),面向数据结构的 Jackson 方法,面向对象的分析方法(Object Oriented Analysis,OOA),以用于建立动态模型的状态迁移图和 Petri 网。

(3)编制需求分析的文档:也就是对已经确定的需求进行文档化描述,该文档通常称为“需求规格说明书”。

(4)需求分析与评审:它是需求分析工作的最后一步,主要是对功能的正确性、完整性和清晰性,以及其他需求给予评价。

1.需求的分类
     什么是软件的需求呢?软件需求就是系统必须完成的事及必须具备的品质。具体来说,软件需求包括功能需求、非功能需求和设计约束三方面内容。各种需求的概念示意图如图8-4 所示。
在这里插入图片描述
功能需求:是指系统必须完成的那些事,即为了向它的用户提供有用的功能,产品必须执行的动作。

非功能需求:是指产品必须具备的属性或品质,如性能、响应时间、可靠性、容错性、扩展性等。

设计约束:也称为限制条件、补充规约,这通常是对解决方案的一些约束说明,例如必须采用国有自主知识版权的数据库系统,必须在 UNIX 操作系统之下运行等。

除了这三种需求之外,还有业务需求、用户需求、系统需求这三个处于不同层面的概念,充分地理解这样的模型才能够更加清晰地理清需求的脉络。

  • 业务需求(Business Requirement):是指反映组织机构或客户对系统、产品高层次的目标要求,通常问题定义本身就是业务需求。

  • 用户需求(User Requirement):是指描述用户使用产品必须要完成什么任务,怎么完成的需求,通常是在问题定义的基础上进行用户访谈、调查,对用户使用的场景进行整理,从而建立从用户角度出发的需求。

  • 系统需求(System Requirement):是从系统的角度来说明软件的需求,它包括用特性说明的功能需求、质量属性、非功能需求及设计约束。 分析师经常围绕着“功能需求”来展开工作,而功能需求大部分都是从“系统需求” 的角度来分析与理解的,也就是用“开发人员”的视角来理解需求。但要想真正地得到完整的需求,仅戴上“开发人员”的眼镜是不够的,还需要“领域专家”的眼镜,要从更高的角度来理解需求,这就是“业务需求”;同时还应该更好地深入用户,了解他们的使用场景,了解他们的想法,这就是“用户需求”。这是一个理解层次的问题,并不仅仅是简单的概念。

2.需求工程
    需求工程就是包括创建和维护系统需求文档所必需的一切活动的过程,主要包括需求开发和需求管理两大工作。

(1)需求开发:包括需求捕获、需求分析、编写规格说明书和需求验证 4 个阶段。在这个阶段需要完成确定产品所期望的用户类型、获取每种用户类型的需求、了解实际用户任务和目标及这些任务所支持的业务需求、分析源于用户的信息、对需求进行优先级分类、将所收集的需求编写成为软件规格说明书和需求分析模型、对需求进行评审等工作。

(2)需求管理:通常包括定义需求基线、处理需求变更、需求跟踪等方面的工作。这两个方面是相辅相成的,需求开发是主线,是目标;需求管理是支持,是保障。换句话说,需求开发是努力更清晰、更明确地掌握客户对系统的需求;而需求管理则是对需求的变化进行管理的过程。

3.需求分析方法
    需求分析的方法可谓种类繁多,不过如果按照分解方式的不同,可以很容易地划分出几种类型。本节先从分析方法发展的历史,对其建立一个概要性的认识,在本章的后面几节中将详细说明最具有代表性的结构化分析与设计、面向对象分析与设计两种方法。

(1)结构化分析方法:最初的分析方法都不成体系,而且通常都只包括一些笼统的告诫,在 20 世纪 70 年代分析技术发展的分水岭终于出现了。这时人们开始尝试使用标准化的方法,开发和推出各种名为“结构化分析”的方法论,而 Tom DeMacro 则是这个领域最有代表性和权威性的专家。

(2)软系统方法:这是一个过渡性的方法论,并未真正流行过,它的出现只是证明了结构化分析方法的一些不足。因为结构化分析方法采用的相对形式化的模型不仅与社会观格格不入,而且在解决“不确定性”时显得十分无力。最有代表性的软系统方法是 Checkland 方法。

(3)面向对象分析方法:在 20 世纪 90 年代,结构化方法的不足在面对多变的商业世界时,显得更加苍白无力,这就催使了 OOA 的迅速发展。

(4)面向问题域的分析(Problem Domain Oriented Analysis,PDOA):现在又发现面向对象分析方法也存在着很多的不足,应运而生了一些新的方法论,PDOA 就是其中一种。不过现在还在研究阶段,并未广泛应用。

8.2.2 如何进行系统设计

     当设计者拿到一个需求,他如何开展系统设计呢?许多想进入系统分析与设计的年轻人以为自己知道了面向对象、统一建模语言、设计模式等新鲜深奥的名词就可以进行设计了,可是掌握工具和技能绝不是成为优秀设计者的充分条件,甚至也不是必要条件。遗憾的是这里没有捷径,只有设计者在实践中不断学习和总结。而在实践中,系统设计与其说是在设计,不如说是在选择和妥协。

    妥协,就是在各个系统目标之间找到一个平衡点。系统目标包括但不限制于功能、性能、健壮性、开发周期、交付日期等。不幸的是,这些目标往往是矛盾的,提高软件性能直接意味着开发周期的增加、交付日期的推迟,盲目地增加功能可能导致性能降低,维护成本提高。软件设计者的难题在于在如此众多的目标之间找到这个平衡点,并且明确知道如何设计能实现这个平衡,既可以让投资者觉得在预算之内,又能让用户相对满意。可行性分析阶段应该已经论述了这样一个平衡点,可是如果设计者发现没有这样一个平点,如同没有一个设计者能让人骑着自行车到月球上去,那么设计者只能提出放弃某个方面的过度要求,否则系统要遭受必然失败的命运。更多的情况是没有经验的设计者不知道是否存在这些平衡点,更不知道如何利用合理的设计及有效的工具来达到平衡。因此设计者需要了解可以解决问题的各种方案,并清楚知道各个方案的效果、成本、缺点,以及这些方案的区别,并在各种方案中进行选择。而这些,不是一个人能在一两天了解的。没有一个设计者会完全重新开始设计一个系统,他们总参考多个与目标系统相类似的系统,再从中进行甄别、取舍和补充来作为新系统的设计。人们发现一个优秀的设计者似乎能在听完需求后就立即构想出目标系统的框架,这并不是因为他聪明或者比不知所措的设计者新手多一个脑袋,而是因为他在平时已经了解大量的系统,对各种设计的优缺点、局限性也了然于胸,能够把以前的设计根据需要再次使用。所以要成为优秀的设计者,了解、掌握、消化、总结前人和自己以前的设计成果是最好的方法,这似乎也是唯一的方法。

    设计者的苦恼有时候和编程人员一样。计算机系统的发展如此迅速,解决方案也越来越多,如同编程语言的发展,同时,随着人类社会的进步,投资者和客户也提出了越来越高的要求,这又需要设计者不断学习、创造新的方案。
    但系统设计也并非没有规律可以遵循,如同幸福的家庭都很相似,不幸的家庭各有各的不幸,人们在实践中发现优秀的系统设计一般在以下几个方面都很出色。

(1)组件的独立性。审视自己设计的系统,是否做到了高内聚、低耦合?
(2)例外的识别和处理。谁能保证系统使用者都精确按照使用说明书使用?
(3)防错和容错。当网络中断、数据库崩溃这样的灾难性事件发生时,系统也跟着崩溃吗?
而且,更幸运的是,也有一些技术能够改进系统设计,这些方法包括:降低复杂性、通过合约进行设计、原型化设计、错误树分析等。

8.2.3 软件设计的任务与活动

    软件设计是一个把软件需求变换成软件表示的过程。最初这种表示只是描绘出软件的总体框架,然后再进一步细化,并在此框架中填入细节。

1.软件设计的两个阶段从工程管理角度,软件设计可以分为两个步骤:

(1)概要设计:也称为高层设计,将软件需求转化为数据结构和软件的系统结构。例如,如果采用结构化设计,则将从宏观的角度将软件划分成各个组成模块,并确定模块的功能及模块之间的调用关系。

(2)详细设计:也称为低层设计,将对结构表示进行细化,得到详细的数据结构与算法。同样的,如果采用结构化设计,则详细设计的任务就是为每个模块进行设计。

2.主要的设计方法比较

     在结构化设计风行的时代,主流的设计方法还包括 Jackson 方法和 Parnas 方法。结构化方法侧重于“模块相对独立且功能单一,使模块间联系弱、模块内联系强”;而 Jackson 方法则是从数据结构导出模块结构;Parnas 方法的主要思想则是将可能引起变化的因素隐藏在有关模块内部,使这些因素变化时的影响范围受到限制,它只提供了重要的设计准则,但没有规定出具体的工作步骤。

    而近年来,对象技术凭借其对数据的高效封装及良好的消息机制,实现了高内聚、低耦合的系统设计,成了现代软件设计的主流方法学。

8.3 结构化分析与设计

    结构化分析与设计方法是一种面向数据流的需求分析和设计方法,它适用于分析和设计大型数据处理系统,是一种简单、实用的方法,曾获得广泛的应用。

8.3.1 结构化分析

    结构化分析方法的基本思想是自顶向下逐层分解。分解和抽象是人们控制问题复杂性的两种基本手段。对于一个复杂的问题,人们很难一下子考虑问题的所有方面和全部细节,通常可以把一个大问题分解成若干个小问题,每个小问题再分解成若干个更小的问题,经过多次逐层分解,每个最底层的问题都是足够简单、容易解决的,于是复杂的问题也就迎刃而解
了。这个过程就是分解过程。

    结构化分析与面向对象分析方法之间的最大差别是:结构化分析方法把系统看作一个过程的集合体,包括人完成的和电脑完成的;而面向对象方法则把系统看成一个相互影响的对象集。结构化分析方法的特点是利用数据流图来帮助人们理解问题,对问题进行分析。

    结构化分析一般包括以下工具:数据流图(Data Flow Diagram,DFD)、数据字典(Data Dictionary,DD)、结构化语言、判定表、判定树。在接下来的部分将对它们一一做简单介绍。结构化系统分析方法从总体上来看是一种强烈依赖数据流图的自顶向下的建模方法。它不仅是需求分析技术,也是完成需求规格化的有效技术手段。

1.结构化分析的工作步骤
    在介绍具体的结构化分析方法之前,先对如何进行结构化分析做一个总结性描述,以帮助大家更好地应用该方法。
(1)研究“物质环境”。首先,应画出当前系统(可能是非计算机系统,或是半计算机系统)的数据流图,说明系统的输入、输出数据流,说明系统的数据流情况,以及经历了哪些处理过程。在这个数据流图中,可以包括一些非计算机系统中数据流及处理的命名,例如部门名、岗位名、报表名等。这个过程可以帮助分析员有效地理解业务环境,在与用户的充分沟通与交流中完成。

(2)建立系统逻辑模型。当物理模型建立完成之后,接下来的工作就是画出相对于真实系统的等价逻辑数据流图。在前一步骤建立的数据流图的基础上,将所有自然数据流都转成等价的逻辑流,例如,将现实世界的报表存储在计算机系统中的文件里;又如将现实世界中“送往总经理办公室”改为“报送报表”。

(3)划清人机界限。最后,确定在系统逻辑模型中,哪些将采用自动化完成,哪些仍然保留手工操作。这样,就可以清晰地划清系统的范围。

2.数据流图
     DFD 是一种图形化的系统模型,它在一张图中展示信息系统的主要需求,即输入、输出、处理(过程)、数据存储。由于从 DFD 中可以很容易地看出系统紧密结合的各个部分,而且整个图形模式只有 5 个符号需要记忆,所以深受分析人员的喜爱,因而广为流行。

    如图 8-5 所示,DFD 中包括以下几个基本元素。过程:也称为加工,一步步地执行指令,完成输入到输出的转换。外部实体:也称为源/宿,系统之外的数据源或目的。数据存储:也称为文件,存放数据的地方,一般是以文件、数据库等形式出现。数据流:从一处到另一处的数据流向,如从输入或输出到一个过程的数据流。实时连接:当过程执行时,外部实体与过程之间的来回通信。
在这里插入图片描述
(1)数据流图的层次。正如前面提到的,结构化分析的思路是依赖于数据流图进行自顶而下的分析。这也是因为系统通常比较复杂,很难在一张图上将所有的数据流和加工描述清楚。因此,数据流图提供一种表现系统高层和低层概念的机制。也就是先绘制一张较高层次的数据流图,然后在此基础上,对其中的过程(处理)进行分解,分解成为若干独立的、低层次的、详细的数据流图,而且可以这样逐一地分解下去,直至系统被清晰地描述出来。数据流图的层次如图 8-6 所示。
在这里插入图片描述
(2)Context 图。Context 图,也就是系统上下文范围关系图。这是描述系统最高层结构的 DFD 图。它的特点是,将整个待开发的系统表示为一个程,将所有的外部实体和进出系统的数据流都画在一张图中。图 8-7 就是一个 Context 图的例子。
在这里插入图片描述
Context 图用来描述系统有什么输入、输出数据流,与哪些外部实体直接相关,可以把整个系统的范围勾画出来。

(3)逐级分解。当完成了 Context 图的建模之后,就可以在此基础上进行进一步的分解。以图 8-7 为例,进行再分解,在对原有流程了解的基础上,可以得到如图 8-8 所示的结果。
在这里插入图片描述
    图 8-8 是在 Context 图的基础上做的第一次分解,而在 Context 图中只有一个过程,那就是系统,将其编号为 0。而接下来对 Context 图进行的分解,其实就是对这个编号为 0 的过程进行更细化的描述,在这里引入了新的过程、数据存储,为了能够区分其位置的级别,在这层次上的过程将以 1、2、3 为序列进行编号。

    由于这是对过程 0 的分解,因此也称之为 DFD 0 层图。而可以根据需要对 DFD 0 层图上的过程(编号为 1、2、3)进行类似的分解,那么就称之为 DFD 1 层图,在 DFD 1 层图中引入的新过程,其编号规则就是 1.1,1.2…,以及 2.1,2.2…,以此类推,直到完成分析工作。

另外,这里存在一个很关键的要点,那就是 DFD 0 层图是 Context 图的细化,因此所有的输入和输出应该与 Context 图完全一致,否则就说明存在着错误。

(4)如何画 DFD。DFD 的绘制是一个自顶向下、由外到里的过程,通常按照以下几个步骤进行。

    画系统的输入和输出:就是在图的边缘标出系统的输入、输出数据流。这一步其实是决定研究的内容和系统的范围。在画的时候,可以先将尽可能多的输入、输出画出来,然后再删除多余的,增加遗漏的。

    画数据流图的内部:将系统的输入、输出用一系列的处理连接起来,可以从输入数据流画向输出数据流,也可以从中间画出去。为每一个数据流命名:命名的好坏与数据流图的可理解性密切相关,应避免使用空洞的名字。

    为加工命名:注意应该使用动宾短语。不考虑初始化和终点,暂不考虑出错路径等细节,不画控制流和控制信息。

3.细化记录 DFD 部件

    为了更好地描述 DFD 的部件,结构化分析方法还引入了数据字典、结构化语言及决 策树、决策表等方法。通过使用这些工具,能对数据流图中描述不够清晰的地方进行有效的补充。其其中数据字典应用最为广泛,下面将详细说明数据字典的相关使用方法。

    数据字典技术是一种很实用、有效的表达数据格式的手段。它是对所有与系统相关的 数据元素的一个有组织的列表和精确严格的定义,使得用户和系统分析员对于输入、输出、 存储成分和中间计算机有共同的理解。通常数据字典的每一个条目中包括以下信息。

① 名称:数据或控制项、数据存储或外部实体的主要名称,如果有别名的还应该将别名列出来。
② 何处使用/如何使用:使用数据或控制项的加工列表,以及如何使用。
③ 内容描述:说明该条目的内容组成,通常采用以下符号进行说明。

  • =:由…构成。
  • +:和,代表顺序连接的关系。
  • [ | ]:或,代表从中选择一个。
  • {}*:n 次重复。
  • ():代表可选的数据项。
  • :表示特定限制的注释。

④ 补充信息:关于数据类型、默认值、限制等信息。下面就是一个数据字典的实例:

  • 客户基本信息=客户编号+客户名称+身份证号码+手机+家庭电话
  • 客户编号 = {0…9}8
  • 客户名称 = {字}4
  • 身份证号码 = [{0…9}15|{0…9}18]
  • 手机 = [{0…9}11|{0…9}12]
  • 家庭电话 =(区号)+本地号区号 = {0…9}4
  • 本地号 = [{0…9}7|{0…9}8]

8.3.2 结构化设计

    结构化设计包括架构设计、接口设计、数据设计和过程设计等任务。它是一种面向数据流的设计方法,是以结构化分析阶段所产生的成果为基础,进一步自顶而下、逐步求精和模块化的过程。

1.概要设计与详细设计的主要任务
概要设计阶段的主要任务是设计软件的结构、确定系统是由哪些模块组成,以及每个模块之间的关系。它采用结构图(包括模块、调用、数据)来描述程序的结构,此外还可以使用层次图和 HIPO(层次图加输入/处理/输出图)。
整个过程主要包括:复查基本系统模型、复查并精化数据流图、确定数据流图的信息流类型(包括交换流和事务流)、根据流类型分别实施变换分析或事务分析、根据软件设计原则对得到的软件结构图进一步优化。

    而详细设计阶段的主要任务则是确定应该如何具体地实现所要求的系统,得出对目标系统的精确描述。它采用自顶向下、逐步求精的设计方式和单入口单出口的控制结构。常使用的工具包括程序流程图、盒图、PAD(Problem Analysis Diagram,问题分析图)、PDL(Program Design Language,程序设计语言)。

2.结构图
     如图 8-9 所示,结构图的基本成分包括模块、调用(模块之间的调用关系)和数据(模块间传递及处理数据信息)。
在这里插入图片描述
    结构图是在需求分析阶段产生的数据流图的基础上进行进一步的设计。它将 DFD 图中的信息流分为两种类型。

变换流:信息首先沿着输入通路进入系统,并将其转换为内部表示,然后通过变换中心(加工)的处理,再沿着输出转换为外部形式离开系统。具有这种特性的加工流就是变换流。

事务流:信息首先沿着输入通路进入系统,事务中心根据输入信息的类型在若干个动作序列(活动流)中选择一个执行,这种信息流称为事务流。

3.程序流程图和盒图
    程序流程图和盒图都是用来描述程序的细节逻辑的,其符号如图 8-10 所示。程序流程图的特点是简单、直观、易学,但它的缺点也正是由于其随意性而使得画出来的流程图容易成为非结构化的流程图。

    而盒图正是为了解决这一问题设计的,它是一种符合结构化程序设计原则的图形描述工具。 盒图的主要特点是功能域明确、无法任意转移控制、容易确定全局数据和局部数据的作用域、容易表示嵌套关系、可以表示模块的层次结构。但它也带来了一个副作用,那就是修改相对比较困难。
在这里插入图片描述
4.PAD 和 PDL
     PAD 是问题分析图的缩写,它符合自顶向下、逐步求精的原则,也符合结构化程序设计的思想,它最大的特点在于能够很方便地转换为程序语言的源程序代码。

    PDL 则是语言描述工具的缩写,它和高级程序语言很相似,也包括数据说明部分和过程部分,还可以带注解等成分,但它是不可执行的。PDL 是一种形式化语言,其控制结构的描述是确定的,但内部的描述语法是不确定的。PDL 通常也被称为伪码。

8.3.3 模块设计

    在结构化方法中,模块化是一个很重要的概念,它是将一个待开发的软件分解成为若干个小的简单部分——模块,每个模块可以独立地开发、测试。这是一种复杂问题的“分而治之”原则,其目的是使程序的结构清晰、易于测试与修改。

    具体来说,模块是指执行某一特定任务的数据结构和程序代码。通常将模块的接口和功能定义为其外部特性,将模块的局部数据和实现该模块的程序代码称为内部特性。而在模块设计时,最重要的原则就是实现信息隐蔽和模块独立。模块经常具有连续性,也就意味着作用于系统的小变动将导致行为上的小变化,同时规模说明的小变动也将影响到一小部分模块。

1.信息隐蔽原则
     信息隐蔽是开发整体程序结构时使用的法则,即将每个程序的成分隐蔽或封装在一个单一的设计模块中,并且尽可能少地暴露其内部的处理。通常将难的决策、可能修改的决策、数据结构的内部连接以及对它所做的操作细节、内部特征码、与计算机硬件有关的细节等隐蔽起来。通过信息隐蔽可以提高软件的可修改性、可测试性和可移植性,它也是现代软件设计的一个关键性原则。

2.模块独立性原则
    模块独立是指每个模块完成一个相对独立的特定子功能,并且与其他模块之间的联系最简单。保持模块的高度独立性,也是设计过程中的一个很重要的原则。通常用耦合(模块之间联系的紧密程度)和内聚(模块内部各元素之间联系的紧密程度)两个标准来衡量,设计的目标是高内聚、低耦合。 模块的内聚类型通常可以分为 7 种,根据内聚度从高到低排序,如表 8-2 所示。
在这里插入图片描述
与此相对应的,模块的耦合性类型通常也分为 7 种,根据耦合度从低到高排序,如表8-3 所示。
在这里插入图片描述
除了满足以上两大基本原则之外,通常在模块分解时还需要注意:保持模块的大小适中,尽可能减少调用的深度,直接调用该模块的个数应该尽量大,但调用其他模块的个数则不宜过大;保证模块是单入口、单出口的;模块的作用域应该在控制域之内;功能应该是可预测的。

  • 19
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

恒二哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值