7.5.1 模块设计
1.结构化设计
结构化设计的目的是在结构化分析过程中建立的逻辑模型基础上, 重点阐述结构化设计的原理与方法, 建立系统的结构。它的基本思想是自顶向下地将电子商务系统划分成若干子系统, 再将每个子系统划分模块, 对每个模块内容进行细化, 确定每个模块的处理流程, 描述模块间的数据关系, 以指导后续的编程工作。
在前面系统总体结构设计已经将系统划分成子系统, 再划分成模块的工作。模块设计阶段主要完成模块的细化任务, 确定每个模块的处理流程, 这个过程是处理流程设计; 然后描述模块间的数据关系, 这个过程是系统流程设计。
(1) 子系统和模块划分的依据
按照结构化设计的思想, 对电子商务系统进行模块划分的依据如下。
①按逻辑划分, 把相类似的处理逻辑功能放在一个子系统或模块中。
②按时间划分, 把要在同一时间段执行的各种处理结合成一个子系统或模块。
③按过程划分, 即按工作流程划分。从控制流程的角度看, 同一子系统或模块的许多功能都应该是相关的。
④按通信划分, 把相互需要较多通信的处理结合成一个子系统或模块, 这样可减少子系统间或模块间的通信, 使接口简单。
⑤按职能划分, 即按管理的功能, 如财务、物资、销售子系统等。
一般来说, 按职能划分子系统、按逻辑划分模块的方式是比较合理和方便的。
(2) 模块内外的联系
在一个电子商务系统中, 系统的各组成部分之间总是存在着各种联系。若将系统或子系统划分成若干模块, 则一个模块内部的联系就是块内联系, 而穿越模块边界的联系就是块间联系。
模块设计的一个基本思想是系统模块结构的独立性, 因此衡量模块的独立性程度有两个重要的指标: 模块耦合和模块内聚。它们从不同的角度反映了模块的独立性。
1) 模块耦合。模块间的信息联系称为模块耦合, 表现了模块的外部特征, 反映出模块之间连接的紧密程度。模块耦合形式和独立性如图7-8所示。
图7-8 模块耦合形式和独立性
①非直接耦合: 两个模块之间没有直接关系, 两者之间不传递任何信息。
②数据耦合: 两个模块之间通过数据交换实现相互之间的联系。
③标记耦合: 一个模块调用另一个模块时, 不是传送数据本身, 而是传送存放数据的变量名或文件名等标记符号。
④控制耦合: 如果一个模块调用另一个模块, 那么所传递的是控制信息, 这两个模块就构成了控制耦合。控制耦合的耦合程度较高, 增加了编程和理解的复杂性
⑤外部耦合: 一组模块全都访问同一全局简单变量, 而且不是通过参数表传递该全局变量的信息。
⑥公共耦合: 一组模块全都访问同一个公共数据环境, 则它们之间的耦合就称为公共耦合。
⑦内容耦合: 一个模块直接访问另一个模块的程序、代码或内部数据。这是最不好的一种耦合形式, 它对模块的独立性破坏最大。
从通用性、可读性和可修改性上讲, 数据耦合最好, 其他依次减弱; 从与其他模块间的联系看, 数据耦合最弱, 其他依次增强。由此可见, 在模块设计时应尽量多地使用数据耦合, 限制使用控制耦合, 尽量避免使用公共耦合和内容耦合。
2) 模块内聚。模块内部自身功能的内在联系称为模块内聚, 也称为模块内部紧凑性。它是用以衡量模块内部自身功能的内在联系是否紧密的指标。模块内聚形式和独立性如图7-9所示。
图7-9 模块内聚形式和独立性
①功能内聚: 一个模块中各个部分都是完成某一具体功能必不可少的组成部分, 或者说该模块中所有部分都是为了完成一项具体功能而协同工作、紧密联系、不可分割的, 则该模块为功能内聚模块。
②顺序内聚: 在模块内, 各成分的执行顺序以确定的顺序进行。一般前一功能成分的输出, 就是后一功能成分的输入, 执行顺序不能改变, 而且这些成分是与同一功能密切相关的。
③通信内聚: 如果一个模块内各功能部分都使用了相同的输入数据, 或产生了相同的输出数据, 则把这种模块称为通信内聚模块。
④过程内聚: 如果一个模块是由若干个为实现某项业务处理、执行次序受同一个控制流支配的功能组合在一起构成的, 那么把这种模块称为过程内聚模块。
⑤时间内聚: 模块中的任务必须在同一时间段内执行, 如初始化模块或终止模块。
⑥逻辑内聚: 将几个逻辑、功能上相似的模块合并, 形成一个新的模块。该模块包括若干个在逻辑上具有相似功能的程序段, 由传送给模块的参数来确定该模块完成哪一程序段的功能。
⑦偶然内聚: 当模块内各部分之间没有联系, 或者即使有联系, 这种联系也很松散,则称这种模块为偶然内聚模块。
模块内聚的好处是使电子商务系统模块容易理解、功能单一、重复利用性好, 也会使后期的程序界面清晰。内聚和耦合是密切相关的, 与其他模块存在强耦合的模块通常意味着弱内聚, 而强内聚的模块通常意味着与其他模块之间存在弱耦合。模块设计追求高内聚和低耦合。
(3) 处理流程设计
处理流程的设计就是将模块细化, 确定每个模块的内部特征, 即内部的执行过程, 包括局部的数据组织、控制流、每一步的具体加工要求及种种实施细节。通过这样的设计,为编写程序制订一个周密的计划。当然, 对于一些功能比较简单的模块, 也可以直接编写程序。处理流程设计的主要内容包括以下2方面。
①选择或设计算法。算法设计涉及所开发项目的具体要求和每个模块的具体功能。为每一模块设计可靠、高效的算法或处理流程是这一活动的目标。
②精确表达算法。对于算法需要给出适当的算法表达形式, 或者说应该选择某种表达工具来描述处理流程。目前最常用的程序结构流程的表达工具有程序流程图。
程序流程图(Program flow chart) 又称程序框图, 是历史最久、流行最广的一种图形表示方法。流程图包括3种基本成分: 加工步骤, 用方框表示; 逻辑条件, 用菱形表示;控制流, 用箭头表示。图7-10所示为几种程序流程图的标准结构。
图7-10 程序流程图标准结构
图7-11所示是某电子商务系统的订单管理模块的程序流程图。
订单管理的流程: 买家提交订单后, 生成一个订单, 再判断买家是否取消订单, 如果是, 则订单结束; 否则买家支付完成后, 由卖家发货。买家收到商品之后, 如果确认收货, 则由平台代收的货款就到了商家银行, 订单结束; 如果买家提出退款申请, 则由卖家确认是否同意退款, 如果卖家不同意, 则双方协商后由买家再次提出退款申请, 一直到卖家同意, 退款完成, 订单结束。
图7-11 某企业电子商务系统订单管理模块程序流程图
程序流程图的优点是直观、形象, 所以容易理解。但从结构化程序设计的角度看, 程序流程图不是理想的表达工具。其缺点之一是表示控制的箭头过于灵活。若使用得当, 则流程图简单易懂; 若使用不当, 则流程图可能非常难懂, 而且无法维护。程序流程图的另一个缺点是只描述执行过程而不能描述有关数据。
(4) 系统流程设计
数据流程图是结构化系统分析阶段描述电子商务系统从输入到信息输出的逻辑过程。结构化系统设计阶段中模块设计使用程序流程图是将模块细化, 确定每个模块内部的执行过程。但在电子商务系统实施时, 还需要了解各个功能模块之间的数据传递关系, 因此需要在模块设计阶段对电子商务系统的系统流程进行设计。事实上, 电子商务系统功能模块数据传递大多是以数据库表的形式进行的, 本节以数据流程图为基础, 将其转换成系统流程图, 用电子商务系统流程图的方式来描述模块间的数据关系。
电子商务系统流程图的图例元素如图7-12所示。
图7-12 电子商务系统流程图图例元素
数据流程图中的数据存储可以转换成系统流程图中的数据库或磁盘文件, 数据流程图中的数据处理可以转换成系统流程图处理。但从数据流程图到系统流程图并非仅仅是符号的改换, 还应考虑哪些处理功能可以合并, 或者可以进一步分解, 然后把有关的处理看成是系统流程图中的一个处理功能。图7-13是一个数据流程图转换为系统流程图的示例。数据流程图中的处理1和处理2进行了合并, 并增加了一个中间文件。
图7-13 数据流程图转换为系统流程图示例
按照上面的转化过程, 可以设计系统流程图。图7-14所示是某企业电子商务系统订单管理模块的系统流程图。
图7-14 某企业电子商务系统订单管理模块的系统流程图
2.面向对象的设计
电子商务系统完成了面向对象的系统分析工作, 提取、整理出了用户的所有需求, 并构建了系统分析模型, 接下来的系统设计工作的主要任务是将系统分析阶段得到的用户需求转变成符合成本和质量要求的、抽象的系统设计方案, 即将系统分析模型转换成系统设计模型, 而且在系统设计过程中不断加深和补充对系统需求的理解, 不断完善系统分析的成果。与结构化方法不同的是, 从面向对象的系统分析到系统设计, 是一个反复迭代的过程, 也是一个不断扩充和完善的过程。从电子商务系统分析到电子商务系统设计的过渡是平滑的, 它们之间没有明显的分界线。
在结构化方法中, 虽然系统设计也需要系统分析的结果作为输入, 但两个阶段所使用的术语、描述工具等存在很大的区别, 这必然增加系统分析和系统设计实现转换和衔接的难度。
而在面向对象的开发方法中, 系统分析的结果多数都可以直接映射成设计结果, 并在设计过程中不断扩充和改进, 从而进一步加深对需求的理解。
(1) 子系统设计
对一个业务比较多的电子商务系统来说, 不可能把所有的业务实体和业务过程放在一个电子商务系统中, 否则会导致电子商务系统过于复杂而难以使用, 因此考虑把电子商务系统分解成若干个子系统。
在UML 中, 将使用包的机制来说明电子商务子系统。因此, 这个阶段的研究任务是考虑如何把一个电子商务系统分成若干包(子系统), 如何描述包与包之间的依赖关系,如何定义电子商务子系统之间的接口。
1) 子系统划分。子系统的划分方法比较多。可以按照电子商务系统的部门划分, 将同一部门应用的软件划分为一个子系统, 也可以按照功能来划分, 将具有相似功能的模块放在一个子系统中。此外, 子系统的划分也可以利用电子商务系统分析阶段对用例分类的结果。
子系统划分完成后, 还要确定子系统之间的关系, 而且在确定子系统之间的关系时,注意尽量使子系统之间的关系保持低耦合。
2) 子系统接口设计。一般而言, 一个电子商务系统的各个子系统之间往往存在一定的依赖关系。它们在业务操作中相互关联。对于这种子系统间的关联, 在设计时需要对其定义接口。
为了降低各子系统之间的耦合性, 对于子系统之间的通信只允许通过接口来实现。定义的接口中包含了子系统间的通信形式和通过子系统边界的消息。外部子系统只能通过接口间接地使用它提供的服务, 不能直接地操作子系统的内容。因此, 只要子系统对外接口不改变, 不管子系统内部发生怎样的变化, 也不会对依赖于该子系统的其他子系统产生影响。
在UML 中子系统及其它们之间关系可以使用组件图来表示。组件图由组件及组件间的接口和依赖关系来构成。图7-15所示是一个“购票” 用例的组件图。其中购买个人票可以通过公用信息亭订购也可直接向售票员购买, 但购买团体票只能通过售票员购买。买票的人可以选择预订销售或个人销售或团体销售中的任意一种方式, 售票处为了方便销售, 需要信用卡付款服务的支持, 同时也必然需要票数据库处在有票可卖的状况中。
图7-15的依赖关系包括以下6种。
①顾客需要信息亭接口提供服务。
②售票员需要职员接口提供服务。
③信用卡付款需要信用卡代理提供服务。
④职员接口需要预订销售、个人销售和团体销售提供服务。
⑤管理接口需要数据库状态提供服务。
⑥售票处需要付款和购买提供服务。
图7-15的实现关系包括以下3种:
①信用卡付款提供付款服务。
②票数据库提供购买和状态查询服务。
③售票处提供预订购买、个人购买和团体购买服务。
图7-15 “购票” 用例的组件图
对于子系统接口的内容描述主要包括以下4个方面。
①操作的名称。
②操作的返回值及其类型。
③操作时要使用的参数名及其参数类型。
④操作主要做什么(给出处理的文字描述, 包括关键的算法)。
(2) 设计类图的建立
在电子商务系统分析阶段所构造的分析模型称为分析类图, 进入设计阶段后需要将其转变为设计类图。虽然在UML 中对于分析类与设计类的符号表示并没有什么区别, 但两者在本质上是有区别的。例如, 设计模型和分析模型的目标不同, 分析模型描述的是用户环境下的业务系统, 而设计模型更多的是从电子商务系统、软件角度出发。
设计类有很多不同类型, UML 为其提供了一种特殊符号, 称为构造型, 可以为不同的类型指定不同的构造型。在UML 中用<< >>符号表示。构造型根据模型元素特定的类型进行分类, 并将类型的名称放到<< >>符号中。
在电子商务系统分析阶段, 分析类有实体类、控制类、边界类3种类型, 设计类同样也包括这3种类型。图7-16所示的表示形式更接近于软件类。
图7-16 实体类、控制类、边界类构造型
图7-17所示为实体类、控制类和边界类之间的协作。
图7-17 实体类、控制类、边界类之间的协作
3.转化
下面给出了从分析类图到设计类图的转化步骤。
(1) 把分析类图中的类和类之间的关系直接转到设计类图中
把电子商务系统分析中确定的各个分析类、类之间的关系以及类的一些属性和方法直接转到设计类图当中, 从而构建出初步的设计类图。这些类中既包括了实体类, 也包括了边界类和控制类。
(2) 细化设计类中的操作及属性
分析类图中所表示的属性都是分析类最主要和最基本的属性, 其并不全面, 需要在设计过程中进一步补充。与此同时, 还要确定这些属性所属的类型。在面向对象的编程语言中既可以使用那些通用的属性类型, 包括日期型、布尔型、整数型等, 也可以使用一些用户定义的属性类型, 操作也要进行细化。
图7-18所示是“资金转账” 在分析阶段的顺序图, 细化操作及其属性, 得到图7-19所示的设计阶段的顺序图。
图7-18 “资金转账” 分析阶段的顺序图
图7-19 “资金转账” 设计阶段的顺序图
(3) 关联关系设计
在设计类图中需要为关联类之间添加导航箭头, 表示源类和目的类之间所发送的带有方向的消息。
识别类之间的关联关系需要注意: 两个对象之间若要进行协作, 则要建立关联关系。如果协作只在一个方向进行, 则建立单向关联。顺序图也描述了设计对象间的相互作用。研究顺序图的消息有助于发现类之间的关联, 也可以根据顺序图或协作图确定关联关系等。
图7-20为根据顺序图确定关联关系。
图7-20 根据顺序图确定关联关系
(4) 添加边界类与控制类之间的依赖关系
对于设计类图中出现的边界类, 为了说明边界类与控制类之间的依赖关系, 还需要画出它们与控制类之间的依赖关系线。
根据以上设计步骤, 下面给出了电子商务系统“订单处理” 设计类图, 如图7-21所示。
图7-21 电子商务系统“订单处理” 设计类图
4.包的设计
在电子商务系统分析阶段使用分析包对电子商务系统的逻辑结构进行了分解, 进入设计阶段后还要继续使用包的概念对子系统进行组织设计。包图是UML 中一个高层次的图,使用包图设计人员可以将具有一定关联性的类联系起来。
将系统中的类进行分组或分包, 可以使模型元素在逻辑上更有秩序, 也体现了系统结构高内聚、低耦合的原则。
电子商务系统设计阶段和分析阶段的包的表示方法基本相同, 同样是使用一个制表方框来表示, 包名一般放在制表方框的标签上, 也可放在方框内部。图7-22所示是电子商务系统按功能划分子系统的包图。
在包与包之间, 或者包中的类与类之间一般存在一定的依赖关系。它表示如果系统中的一个包(或类) 发生了变化, 那么另一个包(或类) 也一定会发生变化。在UML 图中, 依赖关系在包图中一般使用带箭头的虚线来表示。其中箭头指向被依赖的包, 箭尾指向有依赖性的包。
图7-22 电子商务系统按功能划分子系统的包图
设计阶段还可以根据每个设计类所属的具体层次放在不同的包内。在这个过程中, 需要分析每个用例的设计类图和交互图, 最终绘制出电子商务系统的包图。图7-23为电子商务系统设计阶段包图。就这个电子商务系统而言, 系统分解分为3个层次, 顶层是登录及主控程序包; 中间层是6个业务处理包, 即用户管理包、购物车管理包、订单管理包、商品管理包、发货管理包和支付管理包; 底层是电子商务系统实体类包和报表包。
图7-23 电子商务系统设计阶段包图