1 什么是软件设计
软件设计:软件设计是关于软件对象的设计,是一种设计活动,自然具有设计的普遍特性。软件设计既指软件对象实现的规格说明(specification),也指产生这个规格说明的过程
1.1 软件设计思想的发展
1.2 软件设计的核心思想
软件的复杂性是必然的,而不是偶然的
为什么软件会逐渐复杂
- 问题域的复杂性
- 管理开发过程的难度
- 通过软件实现灵活性(可拓展和可变更)
- 不同系统上的不同表现的问题
软件设计的核心思想:分解与抽象。分而治之是软件设计解决复杂度难题的主要思路。
- 分解(Decomposition)是横向上将系统分割为几个相对简单的子系统(subsystem)以及各子系统之间的关系。分解之后每次只需关注经过抽象的相对简单的子系统及其相互间的关系,从而降低了复杂度。
- 抽象(Abstraction)则是在纵向上聚焦各子系统的接口。这里的接口和实现相对,抽象可以分离接口与实现,让人们更好地关注系统本质,从而降低复杂度。
- 层次性(Hierarchy)主要是通过将设计分层,使人们能够更好的专注于层内的设计。
1.3 理解软件设计
设计 = 工程 + 艺术
理性主义 or 经验主义
- 理性主义更看重设计的⼯程性,希望以科学化知识为基础,利⽤模型语⾔、建模⽅法、 ⼯具⽀持,将软件设计过程组织成系统、规律的模型建⽴过程。在考虑到⼈的 因素时,理想主义认为⼈是优秀的,虽然会犯错,但是可以通过教育不断完善⾃⼰ [Brooks2010]。设计⽅法学的⽬标就是不断克服⼈的弱点,持续完善软件设计过程中的不⾜,最终达到完美[McPhee1996]。形式化软件⼯程的⽀持者是典型的理想主义。
- 经验主义者则在重视⼯程性的同时,也强调艺术性,要求给软件设计过程框架添加⼀些灵活性以应对设计中⼈的因素。[Parnas1986]曾指出没有过程指导和完全依赖个⼈的软件设计活动是不能接受的,因为不能保证质量和⼯程性。但是[Parnas1986]也指出⼀些⼈的因素 决定了完全理性的设计过程是不存在的:
- ⽤户并不知道他们到底想要怎样的需求;
- 即使⽤户知道需要什么,仍然有些事情需要反复和迭代才能发现或理解;
- ⼈类的认知能⼒有限;
- 需求的变更⽆法避免;
- ⼈类总是会犯错的;
- ⼈们会固守⼀些旧有的设计理念;
- 不合适复⽤。
所以,[Parnas1986]认为软件设计需要使⽤⼀些⽅法弥补⼈的缺陷,以建⽴⼀个尽可能好的软件设计过程。⽂档化、原型、尽早验证、迭代式开发等都被实践证明能够有效弥补⼈类的缺陷[Parnas1986, Brooks 2010]
2 软件设计的分层
2.1 低层设计
低层设计则深入模块和类的内部,关注具体的数据结构、算法、类型、语句和控制结构等。底层设计的本质是屏蔽程序中复杂的数据结构与算法的实现细节。
主要是对一个方法/函数的内部代码进行设计,通常由程序员独立完成
2.2 中层设计
中层设计更加关注组成构件的模块的划分、导入/导出、过程之间调用关系或者类之间的协作;模块划分隐藏一些程序片段(数据结构+算法)的细节,暴露接口于外界。
通过模块化、信息隐藏、抽象数据类型、封装等方法来实现程序片段间的尽可能的独立。
2.3 高层设计
高层设计基于反映软件高层抽象的构件层次,描述系统的高层结构、关注点和设计决策;
- 部件承载了系统主要的计算与状态
- 连接件承载部件之间的交互
- 部件与连接件都是抽象的类型定义(就像类定义),它们的实例(就像类的对象实例)组织构成软件系统的整体结构,配置将它们的实例连接起来。
- 连接件是一个与部件平等的单位
3 软件设计过程、方法和模型、描述
3.1 软件设计过程的主要活动
3.2 软件设计的方法和模型
软件设计的方法可以分为以下几种:
- 结构化设计方法
- 面向对象设计
- 数据为中心设计
- 基于构件的设计
- 形式化方法设计
静态模型vs动态模型
- 静态模型:静态模型是通过快照的⽅式对系统中时间不变的属性进⾏描述。通常描述的是状态,⽽不是⾏为。(比如一个数字的列表是按大小排序好的)
- 动态模型:动态模型通常描述的是系统⾏为和状态转移。(比如排序的过程中是如何进行排序的)
在结构化设计中,静态模型一般是实体关系图,动态模型是数据流图和结构图;在面向对象设计中,静态模型是类图、对象图、构建图、部署图,动态模型是交互图(顺序图和通信图)、状态图、活动图等
3.3 软件设计描述
设计文档书写要点
- 充分利用标准的文档模版,根据项目特点进行适当的裁剪
- 可以利用体系结构风格的图,让读者更容易把握高层抽象
- 利用完整的接口规格说明定义模块与模块之间的交互
- 要从多视角出发,让读者感受一个立体的软件系统
- 在设计文档中应该体现对于变更的灵活性
Reference
- 南京大学软件学院2022春季学期《软件工程与计算二》