49

由一场奇怪海战引发的软件设计思考

 4 years ago
source link: https://www.tuicool.com/articles/AzYfUfq
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

点击上方" 程序员历小冰 ",选择“置顶或者星标”

你的关注意义重大!

前几天看到了一个博客,推荐了《公理设计》一书,还有其相关的文档以及视频(链接见文末)。简单了解了一下,增深了一些对软件设计的理解,特此也推荐给大家。

公理设计理论将设计建立在科学公理、定理和推论的基础上,由麻省理工学院教授 Nam. P. Suh 领导的研究小组于 1978 年提出,适用于各种类别的设计活动。软件设计当然也属于一类工程设计过程,下面我们就来看一下两者的关联。

奇怪的海战

首先从1862年11月13日的一场海战讲起。这场海战“标志着蒸汽动力铁甲舰新时代的到来。为了便于理解,我这里对舰船名称进行了修改,想了解的朋友可以百度 U.S.S. Monitor battles C.S.S. Virginia.

南方叛军的大大号战舰,体型庞大,非常凶悍。已经击沉了两艘联邦军舰。北方政府军则只派出小小号,一艘非常小,火力也小多的军舰。

bYVnIrb.jpg!web

大大号顾名思义,它船体特别的大,但是都是固定炮塔,两侧和首尾有很多门炮。而小小号虽然小,却有一个可以旋转的炮台。

我们可以理解为一条战舰需要有两个基础功能:调整航行方向和调整炮击方向。

对于大大号,这两个功能需求是耦合 couple 的,要改变炮击方向,就需要将船只转向。而对于小小号,这两个功能需求则是解耦合 decouple 的,航行方向与炮击方向无关,炮击方向可以独立调整。

于是小小号一直尽量守在大大号的射击死角攻击,而大大号虽然火力猛烈则必须不断通过改变航线来调整炮击方向,于是就不断绕圈。这两条船打了4个小时,大大号不得不撤退了,小小号获得了胜利。

由此可见功能之间的解耦十分重要,它增加了便捷性和灵活性。

工科生最爱的映射矩阵

AfaMRbe.jpg!web

书中由海战作为引子,介绍了设计过程中的四个域(Domain):

  • CNs:Customer Needs,客户域,就是客户描述的一大堆自然语言也说不清楚的事情,什么高端大气上档次之类的东西。

  • FRs:Functional Requirements,功能域,从 CNs 域到 FRs 域的变换,就是把客户漫无边际的需求翻译成一些可定量的参数,比如战舰控制系统的 FR 是控制航行方向和控制开炮方向。

  • DPs:Design Parameters,设计参数,或者叫物理域,实现 FRs 的物理参数,比如航向控制器和炮塔控制器。

  • PVs:Process Variables,过程变量,或者叫过程域,是描述实现功能过程中涉及的过程变量。

相邻域之间的映射或转换就是一种设计过程。

例如,用户域元素映射到功能域的过程,实际上是将用户需求转变成产品功能要素的过程,即产品规划;功能域向物理域的映射过程是产品的设计过程;从物理域到过程域的映射则就是我们熟知的软件功能设计过程。

其中最为重要的是FRs(功能需求)到DPs(设计参数)的映射,这也是我们软件开发过程中最长接触的步骤,需求文档有了,如何进行代码设计并实现。

既然是工科的设计理论,怎么能少了特征向量和映射矩阵呢。书中将设计过程定义为相邻域中特征向量之间映射和转换过程。我们下边就简单了解一下书中对矩阵相关的讲述,不感兴趣的小伙伴可以直接去看最后一节。

fIZNvee.jpg!web

书中以矩阵向量的方式讲述了 FRs (功能需求) 和 DPs (设计参数) 的映射关系,也就是上图中由 A 变量组成的矩阵代表着 FPs 到 DPs 的映射。不同的矩阵代表着不同的映射关系,其实我们不需要关心矩阵各个位置的具体值如何计算,只需简化的设定为如果 FP 和 DP 有关联,则矩阵相应位置上的值为1,否则为0。

比如说小小号上的情况,有两个功能需要:FR1(调整航向)和FR2(调整开炮方向);以及两个设计参数:DP1(船舵)和DP2(旋转炮塔),它的映射矩阵如下所示。 jYjAbuN.jpg!web

其中转动船舵的时候,船会转向,所以A11这里是X,同时船身上的炮塔也跟着船一起转向,所以也影响开炮方向FR2,因此A21也是X。而在旋转炮塔的时候,不影响船的航行方向,所以A12这里是0。

好的设计?

所以,基于上边这个映射矩阵,好的设计应该有两个特点:

  • 首先FRs(功能需求)的数量N,应当等于DPs (设计参数)的数量M。

  • 每一个FR(功能需求)与且只与一个DP(设计参数)相互关联。

也就是说映射矩阵是一个对角矩阵,对角线上有值,其他位置都是0。《程序员修炼之道》中也提及了类似的思想,也就是正交性一节。那一节的提示是消除无关事务之间的影响,正好和这里映射矩阵是对角矩阵不谋而合。当映射举证是对角矩阵时,说明 FR 和 DP 一一对应,不会有交叉影响。当某一个 FR 也就是需求发生变更时,只需要修改一个DP。

当然对角矩阵属于比较理想的情况,书中也罗列了一些其他类型的映射矩阵。 AJreQzE.jpg!web

其中最差的情况是 FRs(功能需求)的数量N,小于 DPs(设计参数)的数量M。也就是大大号中的情景:它有两个功能需求,FR1 调整航向和FR2 调整开炮方向,但只有一个DP1 船舵。所以它的映射矩阵如下图所示。 船舵能同时 调整航 向和开炮方向, 就出现了奇怪海战中的高效场景。 UFvY32r.png!web

书中还继续讲解了矩阵分解的知识,也就是对应了需求功能点细分到软件详细设计细分等部分的内容,有兴趣的小伙伴可以自己去看看。

总结

所以书中最后给出两个公理:

  • 独立公理(功能独立性公理)

  • 信息公理(信息量最少公理)

这不正是软件设计中经常提及的松耦合和高内聚嘛。模块相互独立互不影响就是松耦合,最小化信息量就是不对外暴露过多信息,也就是高内聚或者信息隐藏。

-关注我

uMzIbeN.jpg!web

推荐阅读

TCP/IP的底层队列

基于Redis和Lua的分布式限流

AbstractQueuedSynchronizer超详细原理解析

公理设计的论文pdf地址:http://blog.sciencenet.cn/home.php?mod=attachment&id=40989

公理设计公开课视频:https://www.bilibili.com/video/av74189173/


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK