课件

12.6 软件设计过程.pdf

软件设计元素

软件设计是软件开发阶段的重要步骤,它的主要任务是在需求分析的基础上,形成软件系统的设计方案。
image.png
软件交互设计通过分析和理解用户的任务需求,对软件的人机、交互操作逻辑和用户界面进行设计。系统总体设计主要关注系统的质量属性、对整个系统进行模块化的分解,并且选择合适的设计策略。模块设计和实现则是应用良好的设计原则,进一步地细化和实现所分解的模块单元,可能涉及到数据结构、算法设计和数据库设计等。

系统总体设计

系统总体设计是整个软件设计的关键环节,它是在需求分析的基础上定义系统的设计目标,将整个系统划分成若干子系统或模块,建立整个系统的体系结构,并选择合适的系统设计策略。

系统总体设计首先要明确系统应该关注的质量属性,定义系统满足的设计目标。然后按照高内聚、低耦合的原则,把整个系统进行模块化的分解。并且选择系统部署方案,把所分解的模块映射到相应的硬件上。接下来进一步地定义数据存储、访问控制、全局控制等一系列的设计策略。最后通过评审活动来进一步地改进设计质量,确保设计方案的正确性、完备性、一致性和可实现性。

以一个平面规划的例子,来说明如何进行系统设计:
image.png
假设图1住宅的住户是一对夫妻,他们和一个孩子共同生活,要求有单独学习和会客的空间,住户每天行走的路程要求最短,卧室的白天采光量要求达到最大。假设住户大部分的时间集中在客厅/餐厅和主卧室的区域进行活动,那么如何给出满足上述约束的平面规划方案呢?
image.png
设计师根据功能使用的要求把整个住宅划分成两个卧室、一个书房、一个客厅/餐厅、一个厨房和一个盥洗室,形成图2 version1的方案。在这个版本中仔细分析可以发现,厨房和客厅/餐厅的距离太远,不方便用餐时餐具的端进端出,所以我们把卧室 2 和客厅/餐厅进行对换,而且客厅/餐厅调整到南面也有好处,形成 version 2 方案。在版本 2 中,发现厨房和楼梯距离大门太远,所以把大门移动到北边的楼梯上,重新定位卧室 2,并把盥洗室调整到书房旁边,更靠近两个卧室,形成 version 3 方案。
image.png
建筑规划设计和软件系统的总体设计很相以,我们考虑系统的功能需求和非功能需求,把整个系统划分成更为简单的模块和接口,在系统设计发生变化的时候会造成代价很高的返工。

系统设计目标

一般而言,系统的很多质量需求,尤其是非功能需求,主要体现在系统的总体设计方案中,而不是具体的功能模块的实现上。

image.png
性能是影响系统使用的重要因素,主要考虑响应时间、吞吐量和存储量。由于系统的硬件资源和服务能力是有限的,响应时间和吞吐量不太可能同时达到最优,有时候可能以响应时间为代价来获得更高的吞吐量,有时候又要以吞吐量为代价来得到更好的响应时间,所以在设计的时候需要对这两个方面进行权衡。另外也要考虑是采用内存空间来换取更高的速度,还是在可接受的一个速度范围内有限度地使用内存空间。总之,在系统设计时要综合考虑硬件资源和业务使用的情况,来选择合适的方案使系统的性能达到一个可接受的程度。

image.png
可靠性涉及到系统运行时发生崩溃的可能性,系统对可用性和容错性的支持以及安全防范等方面的问题,在系统设计时,需要考虑这些因素在设计方案上给出可能的实现方法。

image.png
系统在投入使用之后还要进行维护和扩展新功能,在系统设计时,也要考虑到如何才能更容易地进行修改,这会涉及到代码的可读性、可扩展性等一系列的属性。

image.png
从最终用户的角度来说,除了要考虑性能、可靠性这些因素之外,还要考虑到是不是可以提高工作效率,或者很容易使用等方面的问题。

image.png
成本也是影响系统设计方案的一个因素,需要考虑开发、部署、升级和维护的成本。

在系统设计时,我们会重点考虑几个少数的主要目标,但是这些目标有可能是互相牵制的,例如开发一个安全、可靠而且廉价的系统可能就是不现实的。在这种情况下,需要优先考虑一些主要的目标,然后再把这些目标来结合其他的目标进行权衡。

权衡设计目标

下面是几种设计目标权衡的例子:
image.png

  • 对于系统性能方面,如果响应时间和吞吐量不能满足系统需求,就有可能使用更多的存储空间来进行加速,如果软件受到存储空间的限制,也有可能牺牲一定的速度对数据进行压缩处理。
  • 在开发管理方面,如果进度出现了延迟,可以考虑减少一定的功能来保证按时的交付,也可以考虑推迟交付的时间保证交付所有的功能。不过在互联网时代,通常及时的上线交付是更重要的。
  • 为了及时上线,有时候也会选择先发布一个有少量缺陷的系统,随后再进行升级和修复。
  • 当然,赶进度也是经常发生,加班是一个有效的方法,在项目的后期,增加人手是不可取的。

确定子系统或模块

image.png
系统设计的一个关键步骤是进行模块化的分解,一般情况下,首先按功能进行模块划分,在此基础上,把数据、硬件、时间要求很高的部分独立出来,并把用户界面、业务逻辑进行分离等等。
image.png
确定系统结构时,可能会选择已有的体系结构风格或者软件框架,这一部分的内容在上一章已经进行了讲解。
image.png
在模块分解之后,可以把这些模块通过简单的统一接口进行封装,从而减少模块之间的依赖程度。

选择系统部署方案

系统设计还要考虑系统运行部署的情况,把所分解的子系统或者模块映射到相应的硬件上,在这个过程中也有可能会增加新的子系统或者模块。

image.png
上图是微信抢票应用的部署方案,后台的管理员使用 PC 端的浏览器进行操作,学生使用手机微信进行操作,抢票的请求由微信的服务器转发给应用服务器,应用服务器处理相应的抢票的业务逻辑,数据库的服务器处理数据的存储,根据这个部署方案可以把抢票应用的子系统或者模块对应到具体的硬件上。

定义设计策略

image.png
对于 Web 应用来说,选择合适的数据存储策略也是非常重要的,一般来说主要是有文件和数据库两种形式。数据库又分成关系数据库、NoSQL 数据库和内存数据库。关于数据库的选择策略,在这里数据库选择策略讲解。

image.png
在多用户系统中,不同角色的用户对系统功能和数据操作有不同的访问权限。比如说微信的抢票应用中管理员可以创建和发布活动,任何用户都可以浏览活动的信息,但是只有校内的学生用户才能参与抢票。

image.png
在微信的抢票应用中,通过学号和密码来识别用户的身份,并且调用校方的验证系统来进行学生身份的验证。

image.png
在系统设计时,还要考虑全局的控制流机制和实现方式,一般来说有三种可能的控制流机制:

  • 过程驱动:在需要来自参与者的数据时,操作等待输入。
  • 事件驱动:主循环等待外部事件,在外部事件到达时,系统根据与事件相关的信息将其分配给适当的对象。
  • 线程:系统创建任意数目的线程,每个线程对应不同的事件。如果某个线程需 要额外的数据,就等待参与者的输入。

对于微信抢票应用来说,可采用单线程、事件驱动和异步任务处理来实现整个控制流。

image.png
最后还要考虑系统的启动、关闭和异常处理等一些边界情况,并且提出具体的实现策略。