软件设计
软件设计就是要构建出一套模型
软件设计到底是什么
它应该包括“模型”和“规范”两部分:
- 模型,是一个软件的骨架,是一个软件之所以是这个软件的核心。模型的粒度可大可小。我们所说的“高内聚、低耦合”指的就是对模型的要求,一个好的模型可以有效地隐藏细节,让开发者易于理解。模型是分层的,可以不断地叠加,基于一个基础的模型去构建上一层的模型,计算机世界就是这样一点点构建出来的。
- 规范,就是限定了什么样的需求应该以怎样的方式去完成。它对于维系软件长期演化至关重要。关于规范,常见的两种问题是:一个项目缺乏显式的、统一的规范;规范不符合软件设计原则。
-
模型与规范,二者相辅相成,一个项目最初建立起的模型,往往是要符合一定规范的,而规范的制定也有赖于模型。
软件设计是什么.png
软件设计至关重要的第一步:分离关注点
最常见的解决问题思路是分而治之,也就是说,我们要先把问题拆分开。在每个问题都得到解决之后,再把这些解决好的子问题以恰当的方式组装起来。如何分解与组合,就是我们要在软件设计中考虑的问题。
要实现一个真实的系统,就不仅仅要考虑功能性的需求,还要考虑非功能性的需求。也就是说,我们在分解问题的时候,会有很多维度,每一个维度都代表着一个关注点,这就是设计中一个常见的说法,“分离关注点(Separation of concerns)”
最常见的一类问题就是把业务处理和技术实现两个关注点混在了一起。在真实项目中,程序员最常犯的错误就是认为所有问题都是技术问题,总是试图用技术解决所有问题。任何试图用技术去解决其他关注点的问题,只能是陷入焦油坑之中,越挣扎,陷得越深。
另外一个常见的容易产生混淆的关注点是不同的数据变动方向。不同的数据变动方向还有很多,比如:
- 动静分离,就是把变和不变的内容分开;
- 读写分离,就是把读和写分开;
- 前面提到的高频和低频,也可以分解开;
- ……
不同的数据变动方向,就是一个潜在的、可以分离的关注点。
大多数系统的设计做得不够好,问题常常出现在分解这步就没做好。常见的分解问题就是分解的粒度太大,把各种维度混淆在一起。在设计中,将一个模块的不同维度分开,有一个专门的说法,叫分离关注点。
分离关注点很重要,一方面,不同的关注点混在一起会带来许多问题;另一方面,分离关注点有助于我们发现不同模块的共性,更好地进行设计。分离关注点,是我们在做设计的时候,需要时时绷起的一根弦。
一个影响软件设计的重要因素:可测试性
另一个经常被很多人忽视的因素:可测试性。软件设计要考虑“可测试性”。
软件开发要解决的问题是从需求而来。需求包括两大类,第一类是功能性需求,也就是要完成怎样的业务功能;第二类是非功能性需求,是业务功能之外的一些需求。非功能性需求也被分为两大类,一类称为执行质量(Execution qualities),你所熟悉的吞吐、延迟、安全就属于这一类,它们都是可以在运行时通过运维手段被观察到的;而另一类称为演化质量(Evolution qualities),它们内含于一个软件的结构之中,包括可测试性、可维护性、可扩展性等。
做设计,其实就是把一个软件拆分成一个一个的小模块。如果不尽可能地保证每个小模块的正确性,而只是从最外围的系统角度去验证系统的正确性,这将会是一个非常困难的过程。要保证每个小模块的正确性,就要保证每个模块在开发阶段能够测试,而想要每个模块能够测试,在设计过程中,就要保证每个模块是可以测试的,而这就是可测试性。有了可测试性的视角,我们可以把它当作一个衡量标准去看待其他的设计或实践,也可以用它帮助我们理解软件的发展趋势。