软件设计

 

 

1 软件设计基础


1.1 一般设计概念

软件并不是有设计的唯一领域。一般而言,我们可以将设计看作是一种问题求解,例如,难题(没有确定性答案的问题)对于理解设计的限制就很有趣,一般意义上,其它许多符号和概念对于理解设计也有趣:目标、约束、候选方案、代表、答案。

 

1.2 软件设计上下文
为理解软件设计的作用,理解其所处的上下文—软件工程生命周期--很重要,这样,理解软件需求分析与软件设计与软件构造与软件测试,就非常重要。

 

1.3 软件设计过程
通常认为软件设计是一个两步的过程
 
1.3.1 体系结构设计
体系结构设计描述软件如何分解和组织成组件(软件体系结构)
 
1.3.2 详细设计
详细设计描述这些组件的特定行为。 软件设计过程的输出是一组模型和人造物品,它们记录了采用的主要决策

 

1.4 使能技术
根据牛津英语词典,“原理”是“一个基本的真理或普遍的法则,用来作为推理的基础或行动的指南”。软件设计原理又称为使能技术,是针对许多不同的软件设计方法
和概念的关键观念。使能技术包括:

1.4.1 抽象
抽象是“遗忘一些信息,使得不同的事物可以当作同样的事物来处理”。在软件设计上下文中,有两个关键的抽象机制:参数化和规范。规范抽象主要由类:过程抽象、 数据抽象和控制(迭代)抽象

 

1.4.2 耦合与聚合
耦合定义为模块之间相互联系的强度,聚合定义为组成一个模块的各个元素如何相互联系。
 
1.4.3 分解与模块化
将大型软件分解和模块化为大量小规模的独立模块,一般目标是将不同的功能或责任放置到不同的组件中。

 

1.4.4 封装与信息隐藏
封装与信息隐藏意味着将元素和抽象的细节分组打包,使得外部不能访问细节


 1.4.5 接口和实现的分离

接口和实现的分离涉及通过规格说明一个公共接口(称为客户)来定义一个组件,并将如何实现细节分离出来。

 

 
1.4.6 充分性、完备性和原始性
要实现充分性、完备性和原始性,就要保证一个软件组件包括了一个抽象的所有重要特征,并且没有多余的特征

 

2 软件设计关键问题

 

设计软件时,必须处理许多关键问题。一些是所有软件都必须处理的质量问题,例如,性能。另一个重要问题是软件组件的分解、组织、打包方法,这个问题很基本,所有设计方法都必须以某种方式处理它。其它的问题“处理软件行为的某些不在应用领域内的方面,而这些行为涉及支持领域”。这些问题通常与系统的功能性横断相交,被成为剖面(aspect),“剖面一般不是软件功能分解的单元,而是以系统的方式影响组件的性能和语义”。下面是一些关键的、横断问题:
 
2.1 并发性
如何将软件分解为多个进程、任务和线程,以处理相关的效率、原子性、同步和调度问题 
 
2.2 实践的控制与处理
如何组织数据和控制流,如何通过不同的机制(如隐含调用和回调)处理交互和临时事件 。

2.3 组件的分布
如何将软件分布到各个硬件上,组件如何通信,如何使用中间件来处理异构软件

 
2.4 错误和异常处理、容错
如何阻止和容许故障,如何处理异常条件

2.5 交互和表现
如何设计结构和组织来实现与用户的交互、信息的表现形式(例如,使用模型-控制器视图方法,将表现与业务逻辑分离)。应该指出,这个主题不是关于如何规格说明用户接口细节的,后者是用户口设计(软件人类工程学的一部分)的任务。

 
2.6 数据持久性
如何处理需要长时间生存的数据

 

3 软件结构与体系结构
软件体系结构是“一个描述软件系统的子系统和组件,以及它们之间相互关系的学科” 

 

3.1 体系结构和视图

可以描述软件设计的不同高层剖面,并形成文档,这些剖面通常称为视图:“一个视图表示了软件体系结构的显示软件系统某个特定特性的某个特定方面”。这些不同
的图点与关联软件设计的不同问题相关,例如:逻辑视图(满足功能需求)与进程图点(并发问题)、物理视图(分布问题)与开发视图(设计如何分解为实现单元)。其它作者使用了不同的术语,例如,行为、功能、结构和数据模型视图。总之,软件设计是多剖面的产品,它由设计过程产生,并由一些相对独立和正交的视图组成

体系结构风格(宏观体系结构模式):体系结构风格是“施加在一个体系结构上的、定义一组或一族满足它们的体系结构的一组约束”。体系结构风格可以被认为是提供软件高层组织(宏观体系结构)的元模型。不同的作者已经标识了大量的主要体系结构风格(1)一般结构(例如,分层、管道线、过滤器、黑板);(2)分布式系统(例如,客户/服务器、3级结构、代理);(3)交互式系统(例如,模型-视图-控制器、表现-抽象-控制);(4)自适应系统(例如,微内核、反射);(5)其它(例如,批处理、解释器、过程控制、基于规则)。

3.2 设计模式(微观体系结构模式)
简洁地讲,模式是“给定上下文中普遍问题的普遍解决方案”。体系结构风格可以被认为是描述软件高层组织的模式(宏观体系结构),其它设计模式可用于描述较低层
次的、更局部的细节(微观体系结构):(1) 创建型模式(例如,构造者、工厂、原型、单件);(2)结构型模式(例如,适配器、接器、组合、装饰器、剖面、蝇量、代理);(3)行为型模式(例如,命令、解释器、代器、协调器、备忘录、观察者、状态、策略、模板、访问者)。

3.3 程序和框架族
另一个复用软件设计和组件的途径是设计程序族,又称为软件产品线。标识族中成员的公共特性,使用可复用可裁剪组件来解决族内成员之间的可变性问题,就可以实现程序族。 在面向对象编程中,一个关键概念是框架:可以通过适当的特定插件(又成为热点)实例化的、部分完成的软件子系统

 

4 软件设计质量的分析与评价

4.1 质量属性
对于得到一个高质量(可维护性、可移植性、可测试性、可追踪性、正确性、健壮性、目的的适应性)的软件设计,多种质量属性都认为是重要的。一个有趣的区分是在运行时间可区别的质量属性(性能、安全性、可用性、功能性、可使用性)、运行时间不可区别的质量属性(可修改性、可移植性、可复用性、可集成性、可测试性)、与体系结构本质质量相关的质量属性(概念完整性、正确性、完备性和可构造性)。

 

4.2 质量分析与评价技术
有多种工具和技术来帮助人们确保软件设计的质量。
(1)软件设计评审:有正式的和半正式的,通常是以小组方式进行,来验证和保证设计结果的质量(例如,体系结构评审[Bas03:c11]、设计评审和检查[Bud04:c4; Fre83:VIII; IEEE1028-97; Jal97:c5,c7; Lis01:c14; Pfl01:c5]、基于场景的技术[Bas98:c9; Bos00:c5]、需求追踪[Dor02:v1c4s2; Pfl01:c11])。  
 (2)静态分析:正式或半正式的静态(不可执行的)分析技术,可以用于评价一个设计(例如,故障树分析或自动交叉检查)[Jal97:c5; Pfl01:c5]。 

(3)模拟与原型:这是评价设计的动态的技术(例如,性能模拟或可行性原型[Bas98:c10; Bos00:c5; Bud04:c4; Pfl01:c5])。

4.3 度量
使用度量可以评定或定量估计软件设计的不同方面:规模、结构、质量。已经提出了许多度量,它们多数依赖产生设计的方法。这些度量可以分为两类。
(1)面向功能(结构化)设计的度量:通过功能分解得到的设计结构,通常表示为结构图(有时称为层次图),可以计算其多种度量[Jal97:c5,c7, Pre04:c15]。
 (2)面向对象设计度量:设计的总体结构通常表示为类图,可以计算多种度量,也可以计算每个类内部的内容的度量[Jal97:c6,c7; Pre04:c15]。

 5 软件设计符号
有许多表达软件设计成果的符号和语言,一些主要用于描述设计的结构组织,另一些用于描述软件行为。某些符号主要在体系结构设计中使用,另一些则主要用于详细设计,少部分可以用于这两个步骤。另外,一些符号通常用于特定方法的上下文中(参见软件设计策略与方法子域)。这里,我们将符号分类为描述结构(静态)视图和行为(动态)视图两类。

5.1 结构描述(静态视图)
下面的符号,主要是(但不总是)图形,描述和表示软件设计的结构方面,即,它们描述主要的组件和组件间的联系(静态视图):
(1)体系结构描述语言(Architecture description languages,ADL):文本(通常是形式化的)语言,以组件和组件间相互联系的方式描述软件体系结构。
  (2)类图和对象图:用于表示类或对象的集合,以及它们之间的联系。
  (3)组件图:用于表示组件([遵从和提供]一组接口的实现的系统的物理的和替代的部分)集合和组件间联系。
  (4)协作责任卡(Collaboration responsibilities cards,CRC):用于表示组件(类)的名称、责任和协作组件名称。
  (5)部署图:用于表示一组(物理)节点,及其相互联系,表示了系统的物理外观 。
  (6)实体联系图:用于表示存储在信息系统中数据的模型。
  (7)接口描述语言(Interface description languages,IDL):类编程语言,用于定义软件组件的接口(输出的操作的名字和类型)。
  (8)Jackson结构图:以顺序、选择和重复的方式描述数据结构。
  (9)结构图:用于描述程序的调用结构(一个模块调用的其它模块,调用某个模块的其它模块)。



5.2 行为描述(动态视图) 下面的符号和语言,一些是图形的,一些是文本的,用于描述软件和组件的动态行为。多数符号用于详细设计。

(1)活动图:用于表示从活动(在一个状态机内进行的非原子执行)到活动的控制流。  

(2)协作图:用于表示发生在一组对象之间的交互,重点是对象、对象的链接、对象在链接上交换的消息。  

(3)数据流图:用来表示数据在一组处理过程之间的流动。  

(4)决策表和决策图:用于表示条件和行动的复杂组合。  

(5)流程图和结构化流程图:用于表示控制流和要完成的对应活动。  

(6)序列图:用于表示一组对象之间的交互,重点在按时间顺序的消息交换 。

 (7)状态变迁与状态图:用于表示状态机中,状态之间的控制流。  

(8)形式化描述语言:文本语言,使用来自数学的基本符号(例如,逻辑、集合、顺序)来严格和抽象地定义软件组件接口和行为,通常形式是前置条件和后置条件。

(9)伪码和程序设计语言:结构化的、类编程语言,通常在详细设计阶段,用于描述一个过程或方法的行为
 

6 软件设计策略与方法
有各种一般的策略来帮助指导设计过程。与一般的策略不同,方法则更为专门,方法通常建议和提供了与方法一起使用的一组符号,并描述了遵循方法时要使用的过程,以及使用方法的指南。这些方法作为传递知识的手段和作为软件工程师小组的公共构架,很有用处[Bud03:c8]。可以参见软件工程工具与方法知识域。
 6.1 一般策略
常常被引用的设计过程中有用的一般策略是分而治之和逐步求精、子顶向下与自底向上、数据抽象与信息隐藏、使用启发式规则、使用模式和模式语言、使用迭代和增
量方法。
 
6.2 面向功能(结构化)设计这是软件设计的一个经典方法,分解的中心集中在标识主要的软件工程上,然后以自顶向下的方式,不断详细描述和精化这些功能。结构化设计通常在结构化分析后进行,产生数据流图对应的过程描述。研究人员提出了各种策略(例如,变换分析和事务分析)和启发式方法(例如,扇入/扇出、影响范围/控制范围)来将一个数据流图变换为通常用结构图表示的软件体系结构。

6.3 面向对象的设计
已经提出了许多基于对象的软件设计方法,这个领域从1980年代中期的基于对象的设计(名词=对象,动词=方法、形容词=属性)发展到面向对象的设计,其中,继承和多态性起着关键的作用,在发展到基于组件的设计,其中,可以定义和访问元信息(例如,通过反射)虽然面向对象设计源于数据抽象,人们提出了责任驱动的设计作为面向对象设计的另一个选择。

6.4 数据结构为中心的设计
数据结构为中心的设计(例如Jackson方法、Warnier-Orr方法)从程序要操纵的数据结构开始,而不是从程序要完成的功能开始。软件工程师首先描述输入输出的数据结构(例如,使用Jackson的结构图),然后基于这些数据结构图来开发程序的控制结构。人们提出了各种启发式规则来处理特殊情况,例如,当输入结构与输出结构不匹配时的情况。
 
6.5 基于组件的设计
一个软件组件是一个独立的单元,具有良定义的接口和可以独立组合和部署的依赖性。基于组件的设计要解决为了改进复用而提供、开发、集成这些组件有关的问题。
 
6.6 其它方法
还有一些其它有趣但非主流的方法:形式化和严密的方法
 

posted @ 2010-06-11 10:24  mozer  阅读(275)  评论(0编辑  收藏  举报