• 《软件方法》第1章2023版连载(01)


    DDD领域驱动设计批评文集

    做强化自测题获得“软件方法建模师”称号

    《软件方法》各章合集


    决定把第8章一部分关于“伪创新”的内容移到第1章,因此此次也更新第1章。


    第1章 建模和UML

    牵着你走进傍晚的风里,看见万家灯火下面平凡的秘密。

    《情歌唱晚》;词:黄群,曲:黄群,唱:曹崴;1994

    1.1 利润=需求-设计

    1.1.1 利润=需求-设计

    利润=收入-成本。不管出售什么,要获得利润,需要两个条件:

    (1)售价要高;

    (2)成本要低。

    妙就妙在,价格和成本之间没有固定的计算公式,这正是创新的动力之源。

    放到软件业上,我也炮制了一个式子:

    利润=需求-设计

    软件开发中,需求工作致力于解决“提升销售”的问题,设计工作致力于解决“降低成本”的问题,二者不能相互取代。能低成本开发和维护某个系统,不一定能保证它好卖。系统好卖,如果开发和维护成本太高,最终还是赚不了多少钱。

    (有的读者可能会想:我做的项目是单位内部项目,不卖钱。那我只能说too simple, sometimes naïve了,可以继续往下看。)

    同上,需求和设计之间不存在,也不应该存在有规律的映射——也幸亏如此,否则人工智能就可以取代人完成。人(即软件开发人员)存在的价值就是在很多种现有可行的映射方案中,努力挑选出其中最好的方案,甚至通过技术革新,创造出更好的方案。

    我们先来看自古以来就有的一个系统,“人肉系统”。

    人肉系统的功能(需求)是(人能够)走路、跑步、跳跃、举重、投掷、游泳……但是设计人肉系统的结构时,并不是从功能(需求)直接映射到设计,得到“走路器官”、“跑步器官”、“跳跃器官”……人肉系统的器官是眼、耳、心、肺、肝、胃、骨架、皮肤……这些器官和人肉系统的功能不是一一对应的,在互相协作以完成系统的功能时,它们和功能之间的关系是多对多的。

    图1-1是某个人肉系统的需求和设计。可以看到,需求和设计的映射是多对多的。各个器官被各个功能共享,不能说“心脏是老板的”、“肺是老爸老妈的”。

    图片

    图1-1 人肉系统的需求和设计

    图1-1的映射只是造物主——用《异形(Alien)》的说法就是工程师(Engineer)——当初挑选的映射方案,今天,人类也成为造物主开始“造人”的时候,我们挑选的映射方案可能和人类的造物主(如果存在)制造人类的映射方案是不一样的,如图1-2。当然,目前人类的科学技术水平,连细胞都造不出来,想要做一样的方案也做不到就是了。

    图片

    图1-2 人类和“新人类”

    如果老板要雇一个民工扛煤气罐,他只要求这个民工能跑能扛,管他体内构造是心肝脾肺肾(如图1-2上部)还是电路板(如图1-2下部)——如果电路板民工更便宜,他会淘汰掉心肝脾肺肾民工;民工找工作也要从市场的需要来找——“有老板雇人扛煤气罐,我可以!”,而不是从自己的内部器官出发来找——“老板,我每天都管理我的心脏,你请我吧!”

    以上所说的这些,总体意思就是:要学会把需求和设计分开,这也是贯彻全书的核心思想,后面还会反复强调——用词可能会有变化,例如“卖和做分开”、“外和内分开”。

    软件开发中,如果从需求直接映射设计,会得到大量的重复代码,成本增加;如果从设计出发定义需求,会得到一堆假的“需求”,卖不出去。总之,利润就会缩水。

    而这一点,很多软件开发人员并没有意识到。

    1.1.2 常见错误

    1.1.2.1 “子系统”其实是需求包

    我们经常听到这样的说法,“本系统分为八大子系统,包括销售子系统、财务子系统、库存子系统……”,这就是需求和设计不分的一个例子。其实,正确的说法可能应该是“本系统的功能需求分为八大需求包……”。

    需求包是基于涉众视角对系统功能分包而得到的,子系统(用UML的说法是组件)是基于内部视角根据系统部件的耦合和内聚情况切割而得到的,这两者不是一一对应的。所谓的“财务子系统”,其实可能是“把财务人员使用的功能放在一个包里”,如图1-3。

    图片

    图1-3 “子系统”其实是需求的分包

    1.1.2.2 “功能模块”是错误用语

    另一个常见的需求和设计不分的说法是“功能模块”。

    功能(Function)。当我们说起这个词的时候,一般指的是系统的功能需求。因为对于组织,一般说“组织的服务”,对于类,一般说“类的操作”。

    不过,“功能需求”仍然不够精确。例如,以自助柜员机(ATM)为研究对象,“取现金”是“功能”,“登录”也是功能,“计算手续费”也是“功能”,到底“功能”有多大?用例的术语要严谨得多。“取现金”是一个用例,“登录”是用例中的一个回合,“计算手续费”是一个步骤。

    因此,“功能”是一个模糊用语。本书在后文会尽量使用严谨的用语,不用模糊用语。

    模块(Module)。当我们说起这个词的时候,研究对象一般是系统。模块表示系统的组成部分,但这个词也是模糊的。这个模块是一个控件?一个类?若干个类形成的组件?

    如果说“功能”和“模块”是模糊的,那么连起来说“功能模块”就是错误的。“功能模块”意味着在意识里认为“功能”和“模块”有直接的映射关系,甚至认为“模块”是属于某个“功能”的模块,是为了完成某个“功能”而存在的。

    我简要归纳需求和设计的区别如图1-4,在后面的章节中再慢慢进一步阐述这些区别。

    图片

    图1-4 需求和设计的区别

    高焕堂在他的书《USE CASE入门与实例》[1]中说过:用例是收益面,对象是成本面。本书基于他的思想做了扩展。

    1.1.2.3 微服务的遮羞布

    最近几年鼓吹的新词“微服务”造成一定的误导。有的人误以为“微服务”就是“需求设计一一对应”。

    假设考虑到开发团队的结构,把系统分成多个“微服务”,分由各个小团队应用各自的技术栈独立完成。例如图1-1中的男士,可能会被分割为“996微服务”、“交作业微服务”、“扛煤气罐微服务”。

    且不说这样划分是否合理,即使这样划分了,“微服务”内部也要通过自己的各个部件(可能是残缺的)协作完成,例如“做作业微服务”要完成“做作业”用例,也需要眼睛、耳朵、手、脚、心脏、**等(可能是残缺的)协作完成,并非映射一个“做作业模块”然后就搞定。更何况,有的用例需要若干个“微服务”协作才能完成。

    另外,“微服务”是妥协的不良结构。如果这样的划分风格所得到的软件结构真的是良好的结构,我们几十年前就可以这样做。即使一个人做的项目,也不妨引入一个假设“由各个小团队应用各自的技术栈独立完成”来改善软件的结构,不必等到今天才大兴“微服务”之风。

    我用盖大楼作类比:

    两座大楼耸立在那里,要判断地震来了哪座大楼不容易塌,要考虑的是大楼的结构、所用的材料、所在位置的地质环境等,和这座楼是哪家公司建造的,要了多少钱,建造大楼的公司内部是怎样的组织结构,一共有几支工程队,当时怎么分工的,甚至大楼是猫建造的、狗建造的、外星人建造的,已经没有直接关系——因为大楼已经在那里了。

    但要研究这些让大楼不容易塌的直接影响因素,涉及到艰深的工程力学、流体力学、岩土力学等知识。架构师李三没把这些知识学扎实,正在那里犯愁呢。

    这时,伪创新专家张四出现了。张四说,时代变了,现在盖楼要讲“新建筑学”,要考虑到人际关系,要搞好团结。

    于是,李三想着反正“老的”工程力学那些我也搞不懂,还是搞“人”轻松一些。这样吧,有几个包工队跟自己混,就分几个包,大家开干就是。

    转换思想后,李三每天累并快乐着,灯红酒绿,推杯换盏。

    而且,运气好的时候,盖出来大楼确实也能住人。

    如果李三说,公司又不是我的,想那么多干什么,这可以理解;

    如果李三和张四说,这么干盖楼快,反正老板要的就是在某某大日子到来之前有个样子货交差,这也可以理解;

    如果李三和张四说,这么干有利于建筑团队的安定团结(虽然坑顾客),这也可以理解;

    但如果李三和张四说,“新建筑学”盖出来的大楼更抗震,甚至到清华大学建筑学院开课“划时代革命性的工程力学”,取代原有的“工程力学”——这就是无耻了!

  • 相关阅读:
    Day31|贪心算法1
    计算机组成原理学习笔记:海明校验码
    java中Calendar类的简介说明
    用VB设计年级人员管理系统
    Cocos Creator3.8 实战问题(二)cocos creator编辑器中绑定事件引发的bug
    《Java极简设计模式》第08章:外观模式(Facade)
    戏说领域驱动设计(九)——架构模式
    内存四区的基本概念
    安全可信 | 首批 天翼云通过可信云安全云工作负载保护平台评估
    要求设计一款温度采样电路,该电路能够根据被测温度的不同,通过红黄绿三种颜色的指示灯来进行显示。
  • 原文地址:https://blog.csdn.net/rolt/article/details/133151816