《软件方法》2023版1.1利润=需求-设计1.2 ABCD工作流

DDD领域驱动设计批评文集

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

《软件方法》各章合集


第1章 建模和UML

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

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

1.1 利润=需求-设计

1.1.1 利润=需求-设计

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

(1)售价要高;

(2)成本要低。

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

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

利润=需求-设计

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

以上说的“利润”、“销售”、“成本”是广义的,可以是金钱,也可以是名声、权力、人力等。

即使你做的是没有在市场上公开出售的单位内部系统,甚至是自己为自己的方便做一个系统,也适用上面的式子。

更为关键的是:需求和设计之间不存在,也不应该存在刻板的一对一映射——也幸亏如此,否则人工智能现在就可以轻易学习其中的映射套路,取代软件开发人员完成所有的工作。目前,软件开发人员存在的价值之一就是根据自己掌握的领域知识和软件开发知识,努力在很多可能的映射方案中挑选出最合适的映射方案,以及创造出更好的映射方案。

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

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

图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)这个词,如果应用于信息系统,描述的是:系统作为一个整体,接收到外部请求时应该产生的效果。

模块(Module)这个词,如果应用于信息系统,描述的是表示系统分解后得到的各个组成部分。

“功能模块”意味着在意识里认为“功能”和“模块”有直接的映射关系,甚至认为“模块”是属于某个“功能”的模块,是为了完成某个“功能”而存在的。

用前面的“人肉系统”来举例,“功能模块”就是“走路器官”、“走路子系统”……,这是错误的。

******

不但“功能模块”不应该连起来说,而且“功能”和“模块”这两个词的含义也是模糊的。

例如,以自助柜员机(ATM)为目标系统,“取现金”是“功能”,“登录”也是功能,“计算手续费”也是“功能”,到底“功能”有多大?“模块”是一个控件?还是一个类?还是若干个类形成的组件?

因此,本书后文中,会尽量使用更精确的术语。例如,以ATM为目标系统,“取现金”是一个用例,“登录”是用例中的一个回合,“计算手续费”是一个步骤,系统里面可能会有一个“账户”类……。

1.1.2.3 微服务的遮羞布

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

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

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

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

“微服务”所要解决的问题,在某些系统中确实是存在的,但我在这里要提醒读者,提防把“微服务”(或类似手段)当成遮羞布。

一个人没有能力解决主要问题时,他可能会采取一些措施来掩盖自己能力不足的事实,其中之一就是引入次要问题。

这也是人之常情了。例如,我们在工作中碰到头痛的问题,有时会逃避着不去碰它,而去做一些整理文件,回复邮件等琐碎的事情来获得成就感。

我用盖大楼作类比:

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

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

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

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

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

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

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

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

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

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

1.1.3 总结

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

图片

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

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

1.1.4 自测题

本书不提供习题答案。

请扫码或访问http://www.umlchina.com/book/quiz1_1.html自测,做到全对自然就知道答案了。

1[单选]

软件开发中需求工作的目的是____。

 A) 让系统更加好卖

 B) 更好地指导设计

 C) 对系统做概要的描述

 D) 满足软件工程需求规范

2[单选]

软件开发中设计工作的目的是____。

 A) 对系统做详细的描述

 B) 更好地指导编码

 C) 降低开发维护成本

 D) 满足软件工程设计规范

3[单选]

开发人员说“根据客户的需求,我们的系统分为销售子系统、库存子系统、财务子系统……”,这句话反映了开发人员可能有什么样的认识错误?

 A) 开发人员没有认识到面向对象设计的重要性

 B) 开发人员直接从设计映射需求

 C) 开发人员直接从需求映射设计

 D) 开发人员没有用UML模型来描述子系统

4[单选]

打开开发人员写的需求规约,发现用例的名字都是“学生管理”、“题库管理”、“课程管理”……,这背后可能隐藏的最大问题是什么?

 A) 用例的名字不是动宾结构,应改为“管理学生”……

 B) 用例粒度太粗,每一个应该拆解成四个用例,“新增学生”、“修改学生”……

 C) 开发人员直接从需求映射设计

 D) 开发人员直接从设计映射需求

5[单选]

以下这些经常在开发团队里使用的词汇,都是不严谨的。其中_______混淆了需求和设计的区别。

 A) 功能模块

 B) 详细设计

 C) 用户需求

 D) 业务架构

6[单选]

关于需求和设计,以下说法正确的是____。

 A) 需求关注概要、设计关注详细

 B) 需求的目的是更好地指导设计

 C) 设计的目的是把系统分解成可以编码的模块

 D) 需求和设计不是一一对应的

7[多选]

有的开发人员没有能力剖析复杂领域逻辑,于是引入性能、开发时间、开发团队组成等遮羞布来转移问题的焦点。以下的哪些做法和这样的做法类似?

 A) 医生在给癌症患者看病时,偷偷借助人工智能来帮忙。

 B) 医生在看病时,对癌症患者说“你经济条件不好,目前只能吃得起这个药,所以这个药最合适”。

 C) 医生在看病时,对癌症患者说“我们医院目前只有这个药,所以这个药最合适”。

 D) 医生看到癌症患者经济条件不好,于是80000元一盒的药只收800元。


1.2 建模工作流

1.2.1 建模工作流ABCD

要能做好需求和设计,以达到“低成本制造好卖的系统”,并非喊喊口号就可以,需要静下心来学习和实践一些必要的建模技能。

软件开发是增量、迭代进行的,每一个迭代周期都需要依次思考这么几个事情:

A-业务建模(business modeling)——定位需要改进的目标组织以及该组织接下来最需要改进的问题。

B-需求(requirements)——描述为了改进组织的问题,所引入的信息系统必须具有的整体表现。

C-分析(analysis)——提炼为了满足功能需求,所引入的信息系统需要封装的核心域机制。

D-设计(design)——考虑质量需求和设计约束,将核心域机制映射到选定非核心域上实现。

本书将以上ABCD称为软件开发的4个建模工作流。

如果采用本书的方法学以及UML表示法,其ABCD大致如图1-5。读者先看一眼即可,后文再详细解说图中内容。

图片

图1-5 四个建模工作流(本书方法学+UML)

软件江湖中各种花里胡哨的用语,不管是真创新还是伪创新,基本上都可以用上面的ABCD来归纳,例如:

产品经理、需求工程师、需求分析师:A+B+部分C。

业务架构师:可能是A(此时“业务”的含义是“组织”),也可能是C(此时“业务”的含义是“核心域”)。

系统架构师:C+D。常有团队说要改进系统架构,其实他想改进的是B-需求。

领域驱动设计:C+D。也有团队声称要学习“领域驱动设计”,其实想解决的却是A-业务建模。

中台:C+D

微服务:C+D

设计模式:C+D

……

欢迎读者随时补充更新。

1.2.2 关于用词

“工作流(workflow)”沿用自RUP(Rational Unified Process)的早期版本,后来的RUP版本改为“科目(discipline)”。

在我看来,“工作流”和“科目”这两个词都不算太好,但目前没有更合适的选择,暂时先用“工作流”。

4个工作流的名称“业务建模”、“需求”、“分析”、“设计”沿用了以往各个方法学的用语,这些用语也不严谨。

例如,“业务建模”末尾有一个“建模”,其他3个却没有,难道其他3个不是建模?如果把其他3个也加上尾巴“建模”,就变成批量刷废话了;如果把“业务建模”的“建模”去掉剩下“业务”,意思已经不对。

甚至“业务”二字都是模糊用语,这个后文再详述。

更贴切的名称可能是:

A-组织价值

B-系统责任

C-核心域逻辑

D-实现

但再三权衡,还是沿用之前的用语。

如果读者真正理解了ABCD的内容,叫什么问题都不大,改成A-阿猫、B-阿狗、C-阿鸡、D-阿鸭也无所谓。

阅读到此处,读者可能会发现,本书中的“需求”和“设计”两个术语有两种用途。

一种用于表达建模得到的结果,例如“需求和设计不是一一对应的”;另一种用于表达建模的工作流,即“B-需求”工作流和“D-设计”工作流,例如“我正在做需求”。

希望下面的话能帮助理解:

为了得到需求,需要做的建模工作流有“A-业务建模”和“B-需求”,为了得到设计,需要做的建模工作流有“C-分析”和 “D-设计”。

1.2.3 逃不掉的思考

在迭代周期中,如果要追求好的结果,按A→B→C→D的顺序来进行推理是必须的,而且各个开发团队一直都在这样做。我们来看几个场景:

开发团队甲,所有成员都认真学习《软件方法》和认真做题,引进了UML和建模工具EA,并按照书中的改进指南改进,最终得到很不错的结果。

开发团队甲的A→B→C→D很容易看出来。

开发团队乙,没听说过《软件方法》,也不用UML和EA,用的是技术总监自己归纳的一套“软件工程方法学”和符号,也还算行之有效。

开发团队乙的A→B→C→D也容易看出来,但形式上和开发团队甲不同。

开发团队丙,快乐拥抱挂着“敏捷”或“领域驱动设计”名头的伪创新。这些伪创新投资少,见效快,门槛低,产量大,仪式感十足。开发团队轻松愉快、热热闹闹地讨论和糊墙。

这里面有A→B→C→D吗?也许有一点,但很少,这些热闹只是装模作样。真正起作用的A→B→C→D推理,可能是在编码的时候在大脑里朦朦胧胧进行的,推理的质量可想而知。

开发团队丁,觉得既然ABC我都不会,我也不想装模作样,就一步到D,直接编码。

这种情况下,还有A→B→C→D吗?有的,和开发团队丙差不多,真正起作用的A→B→C→D推理,是在编码的时候在大脑里朦朦胧胧进行的,同样,推理的质量可想而知。幸好,省去了伪创新装模作样的成本。

开发团队戊的故事(纯杜撰,勿对号入座)看起来有点不一样。他们所在的公司赶上了风口,成了某个领域(例如预制菜)的互联网巨头。在开发和维护预制菜相关的项目时,开发团队戊的领导下觉得现在的前端框架Vue、React等还差点意思——更有可能是为了自己的简历积极主动地“觉得”Vue、React等还差点意思,于是搞了个内部项目,自研前端框架“闪电五连鞭”。过了几年,也许是风潮过了,也许是历史使命已经完成,预制菜市场冷却,反倒是“闪电五连鞭”框架误打误撞,受到全世界开发人员热捧,成为公司的生存支柱。

这里面有A→B→C→D吗?看起来像是颠倒了?

再看一个特别的,程序员张三自己做一个东西给自己用。张三只会用编码工具,也没学过UML或类似的知识。

张三这里面还有A→B→C→D的推理吗?

最后这两个,答案也是一样的,并没有什么特别,具体留到后文详述。

总之,每一个软件项目,只要不是故意摆烂,开发团队都会有A→B→C→D的推理过程——也许无意识、隐式地做,也许有意识、显式地做;也许推理过程严谨合理,也许推理过程漏洞百出;也许分成很多人来做,也许一个人做;推理产物的形式也许是UML模型,也许是其他……

就像一道复杂的数学填空题,答案是97/2023,如果考生能填对这个正确答案,他必然在考试过程中的某个时间点做了正确的推理。只要不是故意摆烂,即使是学渣,也会尝试着去推理。只不过相对于学霸的一击必中,学渣可能要反反复复“敏捷探索”多次才答对,甚至直到考试结束还没答对。

本书希望教给读者一种严谨和高效的推理方法。当然,要掌握它,需要付出辛勤和汗水。

1.2.4 不了解ABCD的危害

1.2.4.1 思维颠倒

如果软件开发人员对以上的“A-业务建模”、“B-需求”、“C-分析”、“D-设计”工作流没有概念,就会出现这样的现象:

问一名开发人员“你在做什么”,他可能回答“我在做设计”、“我在写文档”。

其实,此时他的大脑可能正在思考组织的流程(A-业务建模),或者在思考系统有什么功能性能(B-需求),或者在思考系统要封装的领域概念之间的关系(C-分析),但他通通回答成“在做设计”、“在写文档”。

也就是说,在他的大脑中,软件开发工作被简单地分为“写代码”和“做设计(写文档)”两部分。如果他没有在“写代码”,那么通通是在“做设计(写文档)”。

那么,他是怎么区分自己在“写代码”还是“做设计(写文档)”呢?可能是这样区分的:在Visual Studio、Android Studio、Eclipse……中写出来的叫“代码”,在Word、wiki、Visio、EA……中写或者画出来的叫“文档”。

这时候如果有人忽悠一句口号:代码就是设计,那就更妙了。因为本来我就认为“设计”是“代码以外的各种东西”,现在又说“代码就是设计”,一推导,不就变成了“代码就是(软件开发的)一切”?

即使没有“代码就是设计”这样的忽悠,开发人员也会把“设计”(注意,此处的“设计”不是本书严格定义的D工作流,而是“代码之外的所有东西”)或“文档”看成“代码”的一种比较概要或比较形象的表现形式。不同的“设计”或“文档”代表着“代码”的不同视图,可以让开发人员从不同的视角观察代码,如图1-6所示。

图片

图1-6 误解:文档只是代码的视图

这样的误解不只“普通”的开发人员会有。Martin Fowler所著的UML畅销书《UML精粹》,认为UML有三种用法:草稿、蓝图和编程语言,也是把UML模型看作是代码的视图——这是错误的。虽然Martin Fowler在某些社群的心目中如大神一般存在,但是从Fowler写作的其他书籍《重构》、《企业应用架构模式》、《分析模式》等可以知道,他的研究工作集中在“C-分析”和“D-设计”工作流,在“A-业务建模”和“B-需求”方面研究不多,他在这方面的言论,应谨慎看待。

更危险的是,把“文档”当作“代码”的视图还会带来思维颠倒:先拍脑袋编码,然后再从代码来反推其他工作流的内容,导致其他工作流变成徒有形式的装模作样。

以下是几段我经历过的思维颠倒的对话:

★对话一

我:这个不应该是系统的用例(如果读者不理解什么叫“用例”,就先把它理解为“功能”好了)。

开发人员:是的!我都写好了,运行一下给你看,这个系统确实提供了这个用例。

是否系统的用例应该从“A-业务建模”来推理,通过愿景、业务序列图等步骤的推理后,觉得应该有,系统就有,不该有就没有。不能说,我写好了代码,所以就应该有。

★对话二

我:这两个类的关系不应该是泛化,而是关联。

开发人员:是泛化,不信我打开代码给你看(或:逆向工程转出类图给你看)。

是否泛化关系应该从领域逻辑来判断,领域逻辑不是,那就不是,代码就不应该那样写。不能先写好代码“人是猪的一种”(肯定编译通过),再用写好的代码来证明“人是猪的一种”。

★对话三

我:A聚合(组合)B,这个不太对。

开发人员:对的,你看我代码,A是聚合根,其他对象调用时要先找A,存取数据也是以它作为单元。

同对话二,是否聚合(组合)关系应该从领域逻辑来判断,领域逻辑不是,那就不是,代码就不应该那样写。

如果了解了ABCD工作流的概念,以及不同工作流需要思考和表达的内容,我们可能就不会再说“我在写文档”这种话了。“我在写文档”只是表达“我写的东西不是代码” 或者“我正在用文档编辑工具在工作”。

你在写什么“文档”?“A-业务建模”?“B-需求”?“C-分析”?我不写,我画图,难道不可以吗?我不写不画,我用语音清楚地表达组织的流程,难道不可以吗?我用Word编码(即D-设计),难道不可以吗?我用C#写需求(即B-需求),难道不可以吗?

更有意义的说法应该是“我在做业务建模”、“我在做需求”……如果说“文档”二字可以给你带来不可替代的快感,可以说“我在写业务建模文档”。

1.2.4.2 胡乱应对

开发人员常说要“应对变化”,甚至有的人还喊口号“拥抱变化”,但是很多人并不清楚要应对的是什么样的变化,也不知道应该怎样正确地应对变化。

当我们谈到“变化”的时候,真相有可能是下列之一:

真相(1):根本没有变化

系统的需求(功能、性能和约束)没有变化,只是之前由于实现人员的能力问题,导致实现不能满足需求,或者能满足需求但自认为结构不合理。这样的修改不能叫“应对变化”,只能叫“纠错”。

这种情况下,需要抓的工作流是“C-分析”和“D-设计”。

真相(2):系统的功能没变,性能和约束变了

例如,响应时间缩短,实现平台更换等。

应对这样的变化,需要抓的工作流是“D-设计”,实现的套路要调整。

真相(3):系统功能的合理变化

经过严谨的“A-业务建模”和“B-需求”的推理,认为系统的功能(用例、步骤、输入输出信息、业务规则……)确实需要变化。

应对这样的变化,需要抓的工作流是“C-分析”。

注意,这里说的是经过严谨推理得出的“合理变化”。系统的功能之所以需要变化,根源在于系统所处的大环境中的某些东西发生了变化,而这样的变化往往是有其规律的。通过“C-分析”工作流,调整系统的核心域模型,使其更好地体现核心域的规律,有助于应对这样的变化。

真相(4):系统功能的不合理变化

这就是平时常说的“假需求”。和(1)一样,这其实不是“变化”,是“错误”。

没有经过严谨的“A-业务建模”和“B-需求”的推理,拍脑袋得到的所谓“系统功能”,不能改进组织流程,也不满足涉众利益。

这种情况下,抓“C-分析”工作流意义并不大,因为这种变化没有规律。

需要抓的工作流是“A-业务建模”和“B-需求”。先学会严谨推理出系统的功能,才能知道有没有真相(3)。

我们用医生给患者看病类比:

真相(1):

医生的诊断没问题,开的处方也没问题,护士执行医嘱时执行错了。

这不是“变化”,这是“错误”。如果还把这个叫作“拥抱变化”,就是无耻了。

真相(2):

输液时,换了另外一种品牌的一次性输液器。

真相(3):

患者病情确实有变化。张三原来只是乙肝,现在是肝癌。

这种变化是有规律的。张三得了乙肝却不注意保养,依然酗酒和熬夜,很快进展到肝硬化,然后进展到肝癌。

如果充分了解肝脏的工作机制(C-分析),当张三被诊断出乙肝时,就可以预测和应对后面可能会发生的变化。

真相(4):

医生诊断错了病情。

张三出现恶心、乏力、食欲减退。村里的道士九叔给他诊断,认为他被鬼上身了,需要搞一个驱魔仪式。九叔已经精研驱魔理论体系和实践多年,一手辟邪剑法已经达到传奇王者。

实际上张三是得了乙肝,九叔的传奇王者对此没有帮助。

当然,如果是玩驱魔游戏或Cosplay,又不一样了。

******

也许是不了解其中区别,也许是为了掩盖自己的无能,开发人员经常胡乱应对。

例如,把真相(4)说成真相(3),营造出“需求变化剧烈”的假象,从而掩盖自己缺少“A-业务建模”和“B-需求”能力的事实。

例如,对真相(3)和真相(4)避而不谈,只谈真相(2),或者想通过真相(2)的应对方案“D-设计”来应对真相(3)和真相(4),因为“D-设计”是他唯一熟悉的内容。

一些资料以“领域驱动设计”为名,结果一看内容,所举的例子就1-2个“领域”类,然后就开始讨论Entity、Service、Repository、DTO、六边形架构……哪里有“领域”?分明说的是“企业应用架构模式”、“互联网系统架构模式”。

在各种软件开发技术大会上,也可以看到这样的场景:某电子商务网站的架构师上台讲了一通,接着某视频网站的架构师上台也讲了一通,咦,这两人是同事吗,演讲内容如此相似?原来,他们讲的内容都是“D-设计”的内容。究其原因也许并非不为,而是不能——架构师对自己所开发系统的核心域研究太浅。

1.2.4.3 伪创新泛滥

很多开发人员只有D的知识。当岗位发生变化,需要他做A、B、C的工作时,按道理应该去认真学习A、B、C的技能才对。

可惜,很多人并不愿意走出自己的舒适区,甚至还会有意无意地把其他人拉到自己的舒适区。

例如,在和涉众讨论需求时,频频蹦出一些“技术潮词”,目的就是以自己的“所长”来碾压涉众,从而掩盖自己业务建模(A)和需求(B)技能的不足。

例如,在讨论核心域的类模型(C)时,动不动就谈到如何实现(D)或者质疑“会不会有性能问题”(D),从而掩盖自己抽象能力的不足。

于是,各种投其所好的伪创新就登场了。

有的伪创新极力贬低A、B、C的重要性,通过“砸烂一切枷锁”来吸引热血青年。例如,想那么多有啥用,最后不是还得写代码?张嘴就是Linus Torvalds的“Talk is cheap. Show me the code.”。

后来,“发明家”及其追随者慢慢发现砸烂一切是不行的,追随者的信念开始动摇。于是,伪创新不再贬低A、B、C,而是从D来臆想A、B、C,得到的A、B、C“方法学”非常“简单易学”,让只了解D的开发人员感觉“很受用”。

例如,深入第一线调研各类涉众的利益很麻烦。有办法,摆一个“现场客户”在旁边,开发人员就可以心安理得坐在电脑前面编码,有问题就推给“现场客户”。

例如,认真学习领域知识的各种概念和术语很麻烦。有办法,开发人员可以按照自己的理解创造一套“通用语言”。

伪创新往往不会直接宣传自己“简单易学”,而是会说自己很高深。宣传中往往带有“艺术”、“禅”、“道”等字眼,有意无意地朝宗教、艺术、玄学方向引导——比起枯燥的数学理论和逻辑推理,这些东西可是太好下嘴了。还有一个很大的优势,一些媒体人听到“艺术”、“禅”、“道”等字眼就亢奋,自觉地加入到宣传伪创新的队伍中。

开发人员一开始以为很难很深奥,上手一学,发现其实不难!可以说是:投资少,见效快,产量大,而且仪式感十足。最妙的是,不用走出舒适区辛苦学习,就得到了“方法学”,这可太符合只了解D的开发人员的胃口了!开发人员立刻有捡到了便宜的感觉,心中豪气顿生——不愧是我!别整三岁的,有能耐你整四岁的!

关于各个工作流的各种伪创新,本书后面各章节还会进一步讨论。

1.2.5 没有测试工作流?

“测试”可以看作建模的验证过程,所以不能光说“做测试”,要清楚认识“测试”所验证的内容。

如果“测试”验证的是组织流程中各个系统之间的协作,那就是“A-业务建模”。

如果“测试”验证的是目标系统的整体表现,那就是“B-需求”。

如果“测试”验证的是目标系统内部各个部件之间的协作,那就是“C-分析”和“D-设计”。

无论是启发、定义还是验证,如果你思考的内容是某一个工作流的内容,你就是在做该工作流。在一个迭代周期中,启发、定义和验证往往是交错进行的。

1.2.6 没有项目管理工作流?

本书关注的范围限于方法学,即A→B→C→D的正确推导方法,至于推导是一个人做的,很多人做的,甚至是猫做的、狗做的、外星人做的,没有直接关系。

还是用前面的大楼类比。两幢大楼耸立在那里,地震来了,一幢塌了,另一幢没塌。

直接因素是大楼的结构、所用的材料、所在位置的地质环境等,这些涉及到艰深的工程力学、流体力学、岩土力学等知识——类似于本书所研究和阐述的方法。即使大楼是外星人盖的,也要讲这个基本法。

直接原因往往比较难理解,此处要提防,有的人为了掩盖自己的无能,干脆找比较容易理解的其他原因来把水搅浑。例如,一出事故就嚷嚷“有人吃回扣了”,就算经过调查没人吃回扣,他也会从工作服的颜色,工人是否结对洗澡,施工队开会时是否站立等更容易理解的方面来找原因。

当然,要成功完成一个软件开发项目,还有很多其他工作,例如进度管理、人力资源管理等,但这些都不属于本书讨论的范围。关于软件项目管理方面的内容,读者可自行阅读专门的书籍。

1.2.7 自测题

本书不提供习题答案,请扫码或访问http://www.umlchina.com/book/quiz1_2.html自测,做到全对自然就知道答案了。

1[单选]

以下描述最可能对应于软件开发中的哪个工作流?

每个项目由若干活动组成,每项活动又由许多任务组成。一项任务消耗若干资源,并产生若干工件。工件有代码、模型、文档等。

 A) 业务建模

 B) 需求

 C) 分析

 D) 项目管理

2[单选]

以下描述最可能对应于软件开发中的哪个工作流?

图片

 A) 需求分析

 B) 代码设计

 C) 详细设计

 D) 设计

3[单选]

以下描述最可能对应于软件开发中的哪个工作流?

系统向会员反馈已购买商品的信息。

 A) 功能规约

 B) 需求分析

 C) 需求

 D) 需求规约

4[单选]

以下描述最可能对应于软件开发中的哪个工作流?

在去给外婆拜年的路上,李雪琴突然想起需要一些现金给外婆做现金红包。她先用高德地图查询了附近的ATM机网点,并挑中了一处工行的网点,开车过去一看,好家伙,路边这么多人排队取现金!李雪琴只好又看高德地图,挑了一家她觉得人应该会比较少的,开车过去,终于在ATM机取到了现金,然后,她又想了想哪里有卖红包的地方……

 A) 业务建模

 B) 用户故事

 C) 需求

 D) 流程分析

5[单选]

以下不属于建模工作流ABCD的是______。

 A) 需求

 B) 分析

 C) 设计

 D) 测试

6[单选]

本书中,建模工作流的名称沿用了之前方法学中的名称,这些名称其实都不太合适,例如,______工作流的名称改为“系统责任”更合适。

 A) 业务建模

 B) 需求

 C) 业务需求

 D) 分析

7[单选]

有方法学家发明了比“糊墙”还有仪式感的“美女建模法”。

例如,某医卫领域软件公司招聘一批颜值较高的美女,分别扮演患者、护士、医生、收费员、HIS系统、支付宝、微信等。和客户沟通时,就让这些美女一起上场表演各种场景给客户看。

客户一致反映:这样的方式生动、活泼、新颖、看得见、闻得着、有嚼头、有回昧、一举多得(附加题:这一串的出处是?),下次沟通还这样搞!

请问。美女们向客户表演的最有可能是哪个工作流的内容?

 A) 业务建模

 B) 总体设计

 C) 需求

 D) 分析

UMLChina公众号精选(20231208更新)按ABCD工作流分类

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/227989.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

word文档实现“目录索引中标题加粗、前导符(...)和页码不加粗”效果

文章目录 1 展示论文模板需要呈现的效果2 所遇到的问题2.1 情形1:当更新整个目录后,目录中的所有文字都不加粗2.2 情形2:无法单独选中文字部分,如果相对文字部分加粗,则前导符和页码也会同时加粗 3 解决步骤3.1 步骤1&…

CIDR(无类域间路由)与VLSM(可变长度子网掩码)的区别

CIDR和VLSM的介绍 CIDR CIDR(Classless Inter-Domain Routing,无类域间路由)是一种用于对互联网协议(IP)地址进行聚合和分配的标准。CIDR的引入旨在解决IPv4地址空间的不足和低效分配的问题。在传统的IP地址规划中&a…

关键点检测之修改labelme标注的json中类别名

import json import os import shutil#source_dir表示数据扩增之后的文件夹路径,此时标注的是多分类的标签 #new_dir表示转化之后得到的二分类文件夹def to2class():#json存放路径source_dir r1#json保存路径new_dir r1for i in os.listdir(source_dir):if i.ends…

文本聚类——文本相似度(聚类算法基本概念)

一、文本相似度 1. 度量指标: 两个文本对象之间的相似度两个文本集合之间的相似度文本对象与集合之间的相似度 2. 样本间的相似度 基于距离的度量: 欧氏距离 曼哈顿距离 切比雪夫距离 闵可夫斯基距离 马氏距离 杰卡德距离 基于夹角余弦的度量 公式…

银行数字化转型导师坚鹏:银行数字化转型正在重塑您的工作

您好,我是银行数字化转型导师坚鹏。坚持知行果合一,赋能数字化转型!非常荣幸和您分享关于银行数字化转型如何影响老百姓工作的一些思考。 您知道吗?银行数字化转型给您的工作方式带来新变化、新趋势、新潮流啦!在这个…

一分钟解决:vscode卡在“设置SSH主机:VS Code-正在本地下载 VS Code 服务器”

问题:vscode之前可正常使用,更新之后,连接服务器卡住了。 解决:从CMD或者你的终端连接服务器,进入vscode-server目录下,删除一些文件夹就行,然后使用vscode重新链接,它会自动下载新…

系列七、函数

一、函数 1.1、概述 函数 是指一段可以直接被另一段程序调用的程序或代码。 也就意味着,这一段程序或代码MySQL中已经为我们提供好了,我们要做的就是在合适的业务场景调用对应的函数完成相应的业务需求即可。 1.2、分类 按照业务分类,MySQL中…

基于SSM的影视企业全渠道会员管理系统(有报告)。Javaee项目

演示视频: 基于SSM的影视企业全渠道会员管理系统(有报告)。Javaee项目 项目介绍: 采用M(model)V(view)C(controller)三层体系结构,通过Spring S…

Python将列表中的数据写入csv并正确解析出来

用Python做数据处理常常会将数据写到文件中进行保存,又或将保存在文件中的数据读出来进行使用。通过Python将列表中的数据写入到csv文件中很多人都会,可以通过Python直接写文件或借助pandas很方便的实现将列表中的数据写入到csv文件中,但是写…

计算机毕业设计 基于SpringBoot的物资管理信息系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…

nginx_rtmp_module 之 ngx_rtmp_live_module模块

模块作用 直播模块代码 ngx_rtmp_live_module.c,主要作用是:当客户端推流或者拉流的时候,创建的rtmp session会加入到 live 模块的存储链表中。 模块配置命令 static ngx_command_t ngx_rtmp_live_commands[] {{ ngx_string("live&…

vue3 插槽slot

插槽是子组件中的提供给父组件使用的一个占位符&#xff0c;用 <slot> 表示&#xff0c;父组件可以在这个占位符中填充任何模板代码&#xff0c;如 HTML、组件等&#xff0c;填充的内容会替换子组件的<slot> 元素。<slot> 元素是一个插槽出口 (slot outlet)&…

蓝桥杯专题-真题版含答案-【骑士走棋盘】【阿姆斯壮数】【Shell 排序法 - 改良的插入排序】【合并排序法】

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分…

李宏毅机器学习2023课程记录(1)--课程介绍

李宏毅机器学习2023课程记录(1)–课程介绍 在这里&#xff0c;记录我最近听的李宏毅老师的机器学习课程的一些笔记和感想&#xff0c;进行归纳总结同时方便后续复习回顾。 注&#xff1a;这门课虽然叫做机器学习&#xff0c;但是李宏毅老师讲课主要以深度学习的技术&#xff0…

在Node.js中MongoDB的连接查询操作

本文主要介绍在Node.js中MongoDB的连接查询操作。 目录 Node.js中MongoDB的连接查询操作使用原生的mongodb驱动程序进行连接查询操作使用Mongoose库进行连接查询操作注意项 Node.js中MongoDB的连接查询操作 在Node.js中使用MongoDB进行连接操作&#xff0c;可以使用原生的mong…

AOP切入点表达式和使用连接点获取匹配到的方法信息

目录 第一种 execution(访问修饰符? 返回值 包名.类名.?方法名(方法参数) throws 异常?) 第二种 annotation(com.itheima.anno.Log 首先&#xff0c;自定义一个注解&#xff0c;可以自己随意命名&#xff1a; 第一种 execution(访问修饰符? 返回值 包名.类名.?方法名…

Explain工具-SQL性能优化

文章目录 SQL性能优化的目标Explain中type效率级别&#xff08;重要&#xff09;注意 Explain覆盖索引ExplainindexExplainfilesortExplainfilesort创建 idx_bd(b,d) SQL性能优化的目标 达到 range 级别 Explain中type效率级别&#xff08;重要&#xff09; 显示的是单位查询…

pytorch强化学习(1)——DQNSARSA

实验环境 python3.10 torch2.1.1 gym0.26.2 gym[classic_control] matplotlib3.8.0 numpy1.26.2DQN代码 首先是module.py代码&#xff0c;在这里定义了网络模型和DQN模型 import torch import torch.nn as nn import numpy as npclass Net(nn.Module):# 构造只有一个隐含层的…

LLM大语言模型(二):Streamlit 无需前端经验也能画web页面

目录 问题 Streamlit是什么&#xff1f; 怎样用Streamlit画一个LLM的web页面呢&#xff1f; 文本输出 页面布局 滑动条 按钮 对话框 输入框 总结 问题 假如你是一位后端开发&#xff0c;没有任何的web开发经验&#xff0c;那如何去实现一个LLM的对话交互页面呢&…

Python MySQL数据库连接与基本使用

一、应用场景 python项目连接MySQL数据库时&#xff0c;需要第三方库的支持。这篇文章使用的是PyMySQL库&#xff0c;适用于python3.x。 二、安装 pip install PyMySQL三、使用方法 导入模块 import pymysql连接数据库 db pymysql.connect(hostlocalhost,usercode_space…