查看原文
其他

“创新”何太急-评张逸的“业务服务”(三)系统用例是“深入到系统内部”?(1)

潘加宇 UMLChina 2023-06-27

“创新”何太急-评张逸的“业务服务”(一)业务用例是以目标系统为边界?

“创新”何太急-评张逸的“业务服务”(二)用例的“客观标准”


张逸原文:

如果深入到目标系统内部,思考由系统提供什么样的行为以满足用户的需求,则为系统用例;

我见过不少关于需求的陈述,把用例或需求说成“深入到目标系统内部”的,还是第一次见到。这又是一个“创新”。

为什么张逸会说“深入到目标系统内部”?反复看了他的《业务服务的价值在哪里》原文,张逸可能以为用例规约只表达输入、输出等“可见”的部分,不表达计算、保存等“不可见”的部分,因此“发明”了“业务服务规约”。

其实这是误解。

在张逸文章中提到的Cockburn《编写有效用例》书中就有这样的内容:

图1 摘自Alistair Cockburn的《编写有效用例》
图1中的2)、3)就是“不可见”的部分。
2)、3)之所以是需求,原因并非其“深入到系统内部”,而是它们描述的是系统【作为一个整体】的行为,系统做什么,系统做什么,不涉及“系统由哪些部件组成”,也就是说,没有涉及“系统的内部”。
张逸以为“深入到系统内部”的内容,可能并没有“深入到系统内部”;
张逸以为没有“深入到系统内部”的内容,却有可能涉及到了“系统内部”。
且听我慢慢道来。
~~~~~~~~~~~~
先给出需求的定义:
需求是在涉众利益的平衡之下,系统【作为一个整体】必须满足的功能、性能和设计约束。(为什么叫功能、性能和设计约束,参见我的另一篇文章《“非功能需求”属于模糊术语吗》)
判断需求的标准是:不这样不行。如果不这样,就会有涉众的正当利益受损。
~~~~~~~~~~~~
下面是张逸文章中给出的“业务服务规约”示例,我就根据这个逐一评点,讲一讲其中道理。
张逸原文: 
服务编号:L0006
服务名:发布作品
服务描述:
  作为作者
  我想要发布我的作品
       以便更多读者阅读我的作品
/****************
评点:
此处借鉴了用户故事的表述形式。这种表述形式把不同抽象级别的内容混合在一起,很容易造成废话刷工作量。不过这和本文主题无关,后面我再撰文叙述。
****************/
触发事件:
作者点击“发布文章”按钮
/****************
评点
(1)怎么不讲“统一语言”了?
上面写作品、作品、作品,这里突然来一个“发布文章”,这两个词的不同之处是?
下文除了直接引用原文【作者点击“发布文章”按钮】之外,我统一使用“作品”。
(2)出现“点击”、“按钮”不觉得突兀吗?
“发布文章”属于A领域的知识,“点击”、“按钮”属于B领域的知识,不同领域的知识就这么混合在一起合适吗?
整篇“业务服务规约”,其他的用语都是A领域的词汇,突然出现“点击”、“按钮”等B领域的词汇,作为一名“领域驱动设计”的鼓吹者,这个基本的敏感应该要有的。
而且,张逸在文章中还特别强调:

图2 摘自张逸《业务服务的价值在哪里》
(3)【作者点击“发布文章”按钮】被排除在系统责任之外?
【作者点击“发布文章”按钮】相当于图1中的请求,也可以称为输入。
张逸没有把这一句放在“基本流程”中,可能是认为这一句是作者这个外面的人所做的行为,不属于系统的责任。这可能是造成他以为用例要“深入到系统内部”的原因。
其实,把这句场景式描述转成传统的需求表达形式就是【系统应提供一个“发布文章”按钮供作者点击】,属于系统的责任。负责实现这个系统的人员需要付出精力写出相应的边界类代码。
有意思的是,张逸把输入排除在“基本流程”外,却把输出【发送消息通知作品的订阅者】留在“基本流程”中,这和他“发明”的“菱形对称架构”精神可不一致。
当然,张逸可以解释成:我这个叫“业务服务规约”,作者和作者界面的交互发生在“业务服务规约”的边界之外,也就是说,边界取图3这张UML序列图中虚线画出的边界2。

图3 边界在哪里
即使切换到边界2,订阅者也要和作者同等待遇才合适,系统就不能输出给订阅者了。
(4)不能对系统的部件做“需求”。
这就引出一个很关键的问题,能不能把边界定在边界2来做需求?
不能。这样做得出来的东西不管叫什么都行,但它不是需求。
因为,到底什么是合适的“系统”、“系统边界”在哪里,不是随随便便能定的。
我举个例子:
钟表由零件组装而成。
如果经过定位思考,认为卖钟表是本公司目前的最佳策略,那么钟表就是合适的“系统”。只要本公司的钟表表现出比竞争对手更好的功能和性能就行,至于钟表由哪些零件组成、零件之间如何协作、零件是自己做的还是采购的,无所谓,哪个方案的制造成本低就用哪一个。
千万不能轻飘飘地说“如果我们公司是卖某某钟表零件的呢?”!
每个市场(钟表、钟表零件、钟表零件的零件、钟表零件的零件的零件……)的竞争都是残酷的,把公司卖的产品从钟表改为零件,意味着公司要做一次巨大的转型,这可不是一句“如果”能搞定的。
我们的爸爸不是李刚,市场留给我们的选择并不多,需要花心血去找到“卖什么能让我们活下来”的最佳答案。

图4 卖钟表?卖零件?卖零件的零件?这是一个生死存亡的问题。
这种“轻飘飘说如果”的错误,不只是往“零件”方向想过头,还包括一厢情愿往“钟表”方向想过头。
假如经过思考,认为本公司适合的定位是做零件,那就不要去操钟表企业的心,更不要去操钟表的钟表企业的心。当然,不是说不用关心大趋势,而是说不要入戏太深,自己把自己给忽悠了。
回到软件业。
不知道柴米油盐贵的开发人员,很容易轻飘飘地说“如果把**当成系统呢”。这样的人,如果做程序员老老实实走格子还好说,如果做研发团队领导来画格子,不知道会把研发团队带向何方。
这个世界卖什么的都有,图3中的边界2不是不可以作为可以“卖”的系统,只不过要警惕,不要明明卖的是边界1,却自己骗自己说卖边界2。
不属于需求的内容,可以用类图、序列图、组件图等来表达,不需要逮着一只“用例”可劲地薅羊毛。
(5)【作者点击“发布文章”按钮】可能不是合格的需求
让我们回到图3的边界1。看看【作者点击“发布文章”按钮】符不符合需求的标准。
先来看“作者→发布作品”的涉众。
作者这个执行者是人,是涉众;
发布作品需要素材,素材可能有版权,所以素材版权所有者是涉众(也可能和作者是同一人);
发布作品产生的后果会影响到内容审查机构人员、订阅者以及作品中提到的人(可能作品中未提到任何具体人),这些是涉众。我们给他们排一下位,如图5。

图5 “作者→发布作品”用例的涉众
从图5可以看到,上台表演的演员(Actor)虽然是作者,但在涉众排位时,作者这个演员只排第2位。这还是比较宽松的情况了,如果对版权要求严格,作者的排位还要往后挪。
从这一点也可以看出“用户”这个词的粗陋。
然后,我们问“不这样行吗”——系统不满足【作者点击“发布文章”按钮】可以吗
第1、3、4、5排涉众并不在意作品的发布是不是通过【作者点击“发布文章”按钮】。
内容审查机构人员在意的可能是作品内容不要触犯法律,特别是不要让违法内容巧妙躲过审查,造成大事件让自己背锅;订阅者在意的可能是作品内容是否符合自己的需要;作品内容涉及的人在意的可能是作品内容有没有骂自己或者故意捧杀自己;素材版权所有者在意的可能是自己版权的素材被盗用。这些利益可能和作者的利益是冲突的,所以才会有后面的违规审查等步骤。
只有第2排涉众作者貌似在意,但其实也不在意,在意的可能是发布作品时操作是否方便。
综上所述,系统不满足【作者点击“发布文章”按钮】不一定损害涉众的正当利益。
因此,【作者点击“发布文章”按钮】不是需求,应改为【作者请求发布作品】,传统的表达方式相当于【系统应能让作者通过它请求发布作品】
同样,我们也可以问:系统不满足【作者请求发布作品】可以吗?
不行。作者不能通过系统请求发文,内容审查机构人员倒是轻松了,但作者、订阅者的正当利益都会受损害。
因此,【作者请求发布作品】是需求。
但还不能到此结束。
我们还要问,【作者点击“发布文章”按钮】是怎么冒出来的?
很可能来自设计人员选择的设计方案,他认为这样设计的话,作者这个涉众的发布操作会更方便。
那么,是不是给【作者请求发布作品】这个步骤加一条性能需求【操作要方便】?
没那么简单。
需要看在这个用例的这个步骤中,涉众有没有特定的其他要求。
如果涉众在此处没有特定的要求,只是常规的,能方便点就尽量方便点呗——这是不言而喻的东西,和这个系统、这个用例、这个步骤没有特定关系。需求只需要写【作者请求发布作品】,不用加任何内容。
(有的人就喜欢到处加【操作要方便】等不言而喻的内容,因为这样可以一遍遍地废话刷工作量。)
如果发现这一步比较特别,是竞争的决胜点之一。在这一步要是不比竞争对手“方便”很多的话,涉众很可能就会选择竞争对手(不要嚷嚷“我们的系统没有竞争对手啊”这样的蠢话),而且这并非不言而喻的,那么有必要为这一步补充其他需求。
但是,补充的需求不能写【操作要方便】。这种口号,傻子都会喊。必须给出严谨的度量,例如:
本步骤,作者躯体的平均动作次数不超过**次,平均移动距离不超过**厘米。
这是一条关于可用性的性能需求。
思考什么样的交互界面适合满足这样的需求,是交互设计师的责任;思考如何用软件组件实现交互设计师设计的交互界面,是程序员的责任。
不同岗位不要高估自己的能力。需求人员可能并没有交互设计师和程序员的能力,直接给出界面那就是瞎指挥;程序员自诩什么样的界面都能做,却没有能力判断哪个界面更受欢迎。
【作者请求发布作品】并不阻止设计人员选择【作者点击“发布文章”按钮】这样的设计方案,只不过【作者点击“发布文章”按钮】属于“这样也行”,而不属于“不这样不行”。
误把设计到需求,把“这样也行”当成了“不这样不行”,把本来可以更换的当成了必须坚持的,束缚了自己的手脚,还误以为“需求变化剧烈”,这是典型的“作死”。
(6)【作者点击“发布文章”按钮】才是涉及到了系统的“内部”
【作者点击“发布文章”按钮】好像暴露在外面,肉眼可见,却涉及到了系统的“内部”——它说,系统包含一个按钮的界面控件,按钮上面的文字是“发布文章”。
直接贴一段《软件方法》第6章的文字供参考:
/*
前面说到“建立连接,打开连接,执行SQL语句”不是零件销售系统的需求,可能大家觉得比较好理解,毕竟发生在系统“里面”,看不见,但是步骤中出现界面细节“点击确定按钮”的时候,有的人就觉得这样写好像可以,因为看得见!在需求规约中,在每个用例最后贴一张或几张界面图,大家也觉得很正常。
需求判断的标准不是涉众是否看得见,而是涉众是否在意,否则盲人怎么办?两个非人系统交互怎么办?像之前ATM的例子中,涉众看不见“系统记录取现信息,更新账户余额”,但是涉众在意,必须写,而“单击确定按钮”即使看得见,也不能写,因为涉众不在意。
界面组件和数据库组件一样,都是系统设计的一部分。以人肉系统作为例子,藏在人肉系统内部的心脏是人的设计,露在外面的眼睛也同样是设计。人肉系统的需求是“能看”,未必需要单独分出“眼睛”这样一个器官。如果有一种新人类,没有分出眼睛耳朵鼻子等器官,只是头上有一个360°接收器接收各种声光和气味信号并传到内部处理,没准这样的新人类更适合在这个社会上生存。另外,人光有眼睛这个输入设备,没有血液循环系统和神经系统的帮忙,也无法让大脑感知到外部信息,达到“能看”的目的。第一章已经说过,需求和设计不是一一对应,而是多对多的。
*/
也可以对比【作者请求发布作品】,这样的表达说的是系统的整体,没有暗示任何的系统部件。
同理,后面提到的【检查作品是否符合发布标准】虽然肉眼看不见,却可以是需求。这一句说的也是系统的整体,没有暗示任何的系统部件,而且系统要是不【检查作品是否符合发布标准】,就有可能损害第1排涉众-内容审查机构人员的利益。
如果写成【系统通过“检查作品是否符合发布标准微服务”检查作品是否符合发布标准】,才是涉及到了系统的部件——“深入到系统内部”
(7)什么时候【“发布文章”按钮】会成为需求?
当涉众直接要求,不这样不行的时候。
例如,有关机构制作了一个【“发布文章”按钮】控件,强制要求各种有类似于“发布作品”用例的系统,在实现该用例时,必须使用这个【“发布文章”按钮】控件,否则该系统不允许发行。
但是,需求不能直接写【作者点击“发布文章”按钮】,要分成两条写:
步骤:作者请求发布作品
设计约束:必须使用有关机构提供的【“发布文章”按钮】控件。
步骤要比设计约束稳定。把稳定和不稳定的需求分开,就不会乱喊“不得了了,需求变了”——慌什么?哪个级别的需求变了?用例?路径?步骤?约束?还是需求根本没变,只是之前对需求的认识是错误的?
************
针对张逸“业务服务规约”示例接下来内容的简要评点见下,有时间再详述。
基本流程:
1.检查作品是否符合发布标准
2.对作品内容进行违规检查
(“进行”是弱动词,再加一个“对”,形成双重废话。)
(两句检查可以合为一句。)
3.发布作品
(怎么不写“对作品进行发布”?)
(另外,不保存吗?是漏了,还是真的不用保存?或者说发布就是保存?)
4.发送消息通知作品的订阅者
(通知就通知,为什么加一个冗余的“发送消息”,是有什么特别含义吗?)
读者订阅的是作品吗?这篇作品还没发布呢!读者订阅的对象估计是某个作者、某个专栏或某个主题,然后该作者、专栏或主题有新作品时就通知,这样更合理一些。)
(当然,“订阅作品”这个可以想办法圆过来。周杰伦宣布一个月之后发新单曲,预订的歌迷可以打99折,这时歌迷“订阅”的确实就是这个单曲了。也许张逸的“订阅”指的是这个吧。)
(可能还漏写了一个输出——反馈给作者说文章已发布。不管实现起来是弹个消息还是“嘀”一声响,不反馈的话,作者怎么知道刚才一顿操作猛如虎是不是白干了。)

替代流程:

  1a.如果作品不符合发布标准,提示“作品不符合发布标准”

  2a.如果作品内容未通过违规检查,提示“作品内容包含敏感内容,禁止发布”

  3a.如果作品发布失败,提示失败原因

(3a,为什么会发布失败?数据库设计不合理、程序员编码有问题、网络带宽不足、网线断了、硬盘坏了、停电了……这些和需求无关。换个人做、换个软件硬件解决方案,可能就不会发生。另外,这些原因和本步骤、本用例、本系统有什么特定关系吗?)

(同理,第4步怎么不写“通知失败”?数据库设计不合理、程序员编码有问题、网络带宽不足、网线断了、硬盘坏了、停电了……也会造成通知失败的呀?包括【作者点击“发布文章”按钮】都会失败,程序员忘了给点击事件编写代码嘛。)

(需求里要写的失败是:即使编码、数据库设计、网络带宽……没有问题,这种失败也不能避免。例如1a、2a,即使目标系统的编码、数据库设计、网络带宽……没有问题,也没法保证作者输入的内容合法,因为作者这个人的代码是他老爸老妈写的,不是目标系统的程序员写的。)

验收标准:

  1.作品标题字数不得超过50个字符(1个汉字为2个字符)

  2.作品标题只能使用汉字、英文字符和数字

  3.发布的作品必须包含标题、作品类型和作品内容,作品内容的字数不能少于300字

(这些属于需求的一部分,业务规则,而且应该指明绑定到哪个步骤,是步骤2?还是步骤3?)

(另外,还缺了字段列表。业务规则提到了必须包含标题、作品类型和作品内容这3项,但没有讲清楚,要提交的作品信息项到底只包括这3项?还是要提交的作品信息项>3项,其中这3项是必须的。

  4.作品发布成功后,状态为“已发布”

(这种表述属于“意识流”。什么叫“发布成功后”?“状态”又是什么?另,需求里没有“状态”,有的只是规则,至于规则是通过“状态”还是其他思考范式来达到,属于设计问题。)

  5.作品的订阅者收到作品发布的通知

(什么叫“收到”?即使把边界放在图3的边界1,系统也没法承诺订阅者收到,最多能承诺已经通知。随意书写系统不能承诺的事情,会模糊了系统的契约,以为一用上这个用例,订阅者就会收到。)

  6.作品的订阅者可以阅读已发布的作品

(同样属于“意识流”,什么叫“可以阅读”?订阅者眼睛突然瞎了,需要骂目标系统没尽到责任吗?)

(订阅者如果是通过其他手段阅读已发布的作品,那么这是目标系统无法感知和承诺的;)

(订阅者如果是通过目标系统来阅读已发布的作品,那就意味着这个用例还承诺了系统会有一个“订阅者→阅读已发布的作品”用例,也就是说,如果“订阅者→阅读已发布的作品”用例出了意外,意味着本用例的责任就还没尽到!这合理吗?)


待续……


12月16-19晚剔除“伪创新”和“无领域”的领域驱动设计-网络公开课

DDD话语评价之二:“值对象”是DDD的创新吗(全文)

[全文]DDD话语批评之一:评张逸的“状态和事件本质相同”

UMLChina建模竞赛题大全-题目全文+分卷自测(11套110题)

全程字幕-25套UML+Enterprise Architect/StarUML建模示范视频

[新增:鸵鸟]软件开发团队的脓包:皇帝的新装、口号党、鸵鸟、废话迷

《软件方法》书中自测题-题目全文+分卷自测(1-8章)16套111题

怪论:东北公司用用例做需求,反映了东北互联网落后?

别把洋垃圾当宝贝-评InfoQ中国“敏捷……”文章(一)

CTO也糊涂的常用术语:功能模块、业务架构、用户需求……[20210217更新]

UMLChina服务介绍



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存