1.3 建模工作流
要达到“低成本制造好卖的系统”的目标,并非喊喊口号就可以,需要静下心来学习和实践以下各个建模工作流中的技能。
1.业务建模——描述组织内部各系统(人脑系统、电脑系统……)如何协作,使得组织可以为其他组织提供有价值的服务。新系统只不过是组织为了对外提供更好的服务,对自己的内部重新设计而购买的一个零件。组织引进一个软件系统,和招聘一名新员工没有本质区别。如果通过业务建模推导新系统的需求,而不是拍脑袋得出,假的“需求变更”会大大减少。
2.需求——描述为了解决组织的问题,系统必须具有的表现——功能和性能。这项技能的意义在于强迫我们从“卖”的角度思考哪些是涉众(Stakeholder)在意的、不能改变的契约,哪些不是,严防“做”污染“卖”。需求工作流的结果——需求规约是“卖”和“做”的衔接点。
3.分析——提炼为了满足功能需求,系统需要封装的核心域机制。可运行的系统需要封装各个领域的知识,其中只有一个领域(核心域)的知识是系统能在市场上生存的理由。对核心域作研究,可以帮助我们达到基于核心域的复用。
4.设计——为了满足质量需求和设计约束,核心域机制如何映射到选定平台上实现。
软件开发人员如果缺乏软件工程方面的训练,对以上工作流没有概念,就会把这些工作产生的工件通通称为“设计”或者“文档”。例如问开发人员在做什么,回答“我在做设计”“我在写文档”,其实他的大脑可能正在思考组织的流程(业务建模),或者在思考系统有什么功能性能(需求),或者在思考系统要包含的领域概念之间的关系(分析),但他通通回答成“在做设计”“在写文档”。后来又有牛人说了:代码就是设计。本来“设计”在他脑子里就是“代码以外的东西”,这么一推导,不就变成了:代码就是一切?
很多大谈“编码的艺术”的书籍和文章,其实探讨的根本不是编码的技能,而是分析技能甚至是业务建模技能,只是作者的大脑里没有建立起这些概念而已。编码确实有编码的技能,就像医院里护士给患者输液也需要经过训练,但如果患者输液后死亡,更应该反思的是护士的输液手法不过关,还是医生的检查诊断技能不过关?
把工件简单分割为代码和文档(或设计),背后还隐含着这样的误解:认为模型(文档)只不过是源代码的另一种比较概要或比较形象的表现形式。这种误解不只“普通”的开发人员会有,一些著名的UML书籍作者也有。Martin Fowler(1)所著的UML畅销书《UML精粹》,认为UML有三种用法:草稿、蓝图和编程语言,也是仅从编码的角度来说的。从Fowler写作的其他书籍《重构》《企业应用架构模式》《分析模式》等可以知道,他的研究工作集中在分析设计工作流,特别是设计工作流,在业务建模和需求方面研究不多。
不同工作流产出的工件之间的区别不在于形式,而在于内容,也就是思考的边界,如图1-3所示。如果清楚了解这一点,即使用C#,照样可以表达需求,用Word也可以“编码”。
图1-3 建模工作流思考边界
有的开发人员思维刚好是颠倒的,先拍脑袋实现,然后再从实现反推前面的内容,例如下面的对话。
顾问:这个不应该是系统的用例。
开发人员:是的!我都写好了,运行一下给你看,这个系统确实提供了这个用例。
顾问:这两个类关系不应该是泛化,而是关联。
开发人员:是泛化,不信我打开代码给你看,或者逆向工程转出类图给你看。
是否系统用例应该以“好卖”来判断,是否泛化关系应该以“符合领域内涵”来判断,而不是先写好代码,再用代码来证明。
一些不了解以上概念的软件开发人员干脆以“敏捷”“迭代”为名,放弃了这些技能的修炼。就像一名从护士成长起来的医生,只掌握了打针的技能,却缺少检查、诊断、拟治疗方案等技能,索性说:“唉,反正再高明的大夫,也不能一个疗程把患者治好,干脆我也别花那么多心思了,先随便给患者打一针看看吧,不好再来!”“迭代”只是一个底线,确实,再高明的大夫也没有把握一个疗程就治好患者,所以要按疗程试试看,但是在每一个疗程中,依然要尽力检查、诊断、拟治疗方案。检查、诊断等技能越精湛,所需要的疗程就越少。
唱曲的名家,唱到极快之处,吐字依然干净利落;快节奏的现代足球,职业球员的一招一式依然清清楚楚;即时战略游戏高手要在极短时间内完成多次操作,动作依然井然有序。
有的开发团队用“项目时间太紧”作为放弃建模的理由,这个理由是不成立的。以高考做类比,如果一年之后要高考,学霸会认真做一年的计划,再做一周的计划,再做每天的计划,找出分值最大而自己又最薄弱的地方先复习,并且随进度调整计划,不断提高,最终考了700分。学渣则浑浑噩噩,零敲碎打,最终考400分。假设教育部门突然下令,一周之后就要高考!学渣可能心里暗喜,以为自己翻身的机会来了。学霸依然会认真做一周的计划,再做每天的计划,找出分值最大而自己又最薄弱的地方先复习,并且随进度调整计划,不断提高,最终考得550分。学渣虚度了一周时间,考了350分。有一个著名的学渣,每隔四年失败一次。每次失败后总结教训“备战时间仓促”,其实再给学渣四年,它也是混四年,最终还是那个样子——你猜这个学渣是谁?
在激烈竞争的年代需要快速应变,掌握技能才能真敏捷。世上无易事,偷懒要不得。不能把“敏捷”“迭代”作为偷懒的庇护所。
有些互联网开发人员鼓吹“试错大法”,主张拍脑袋拿出去让市场试错,这同样是很荒谬的。客户确实不管你是怎么开发的,他只需要挑好用的就行,但对于开发系统的组织来说,有没有被挑中则是致命的。就像奴隶主看角斗士厮杀,奴隶主无所谓谁胜谁负,反正过程精彩,最终嘉奖冠军就行,而每一个角斗士却要如履薄冰,想方设法让自己坚持到最后。可悲的是,互联网公司是角斗士,却偏偏有“我是奴隶主”的错觉。
刚入行的开发人员体会不到建模的重要性,是正常的。就像下象棋,初学者面对单车对马双士、单马对单士等已经有共识的局面还需要思考良久,最终还拿不下来,甚至输掉。这时中局和布局的书在他看来多半是枯燥无味的,还不如把一本实用残局汇编看熟了,学到一些雕虫小技,也能在菜市场赢几盘棋。不过,要迈向职业棋手的境界,参与更残酷的竞争,就体现出中局和布局的重要了。
从我的观察所得,以上四项技能,大多数软件组织做得较好的是设计(也就是实现),前面三项都相当差,特别是业务建模和分析,没有得到足够的重视。很多软件组织拍脑袋编造需求,然后直扑代码,却不知“功夫在诗外”。
本书中的“需求”和“设计”两个术语有两种用途。一种用于表达建模得到的结果,例如“需求和设计不是一一对应的”;另一种用于表达建模的工作流,即需求工作流和设计工作流,例如“我正在做需求”。希望下面的话能帮助理解:为了得到需求,需要做的建模工作流有业务建模和需求,为了得到设计,需要做的建模工作流有分析和设计。
到目前为止,我没有谈到UML。只要您思考过上面四个工作流的问题,就是在建模。可以用口头表达,也可以用文本、UML、其他表示法或自造符号来表达。在每一个项目中,开发团队肯定会思考和表达上面这些问题,只不过可能是无意识地、不严肃地做。现在,我们要学习有意识地做,而且把它做出利润来。使用UML来思考和表达是目前一个不坏的选择。
本书不提供练习题答案,请扫码或访问http://www.umlchina.com/book/quiz1_2.htm完成在线测试,做到全对,自然就知道答案了。
1.开发人员说“根据客户的需求,我们的系统分为销售子系统、库存子系统、财务子系统……”,这句话反映了开发人员可能有什么样的认识错误?
A)开发人员没有认识到面向对象设计的重要性
B)开发人员直接从设计映射需求
C)开发人员直接从需求映射设计
D)开发人员没有用UML模型来描述子系统
2.打开开发人员写的需求规约,发现用例的名字都是“学生管理”“题库管理”“课程管理”……,这背后可能隐藏的最大问题是什么?
A)用例的名字不是动宾结构,应改为“管理学生”……
B)用例粒度太粗,每一个应该拆解成四个用例,“新增学生”“修改学生”……
C)开发人员直接从需求映射设计
D)开发人员直接从设计映射需求
3.以下这些经常在开发团队里使用的词汇,都是不严谨的。其中_______混淆了需求和设计的区别。
A)功能模块
B)详细设计
C)用户需求
D)业务架构
4.以下描述最可能对应于软件开发中的哪个工作流?
每个项目由若干活动组成,每项活动又由许多任务组成。一项任务消耗若干资源,并产生若干工件。工件有代码、模型、文档等。
A)业务建模
B)需求
C)分析
D)设计
5.以下描述最可能对应于软件开发中的哪个工作流?
A)业务建模
B)分析
C)需求
D)设计
6.以下描述最可能对应于软件开发中的哪个工作流?
系统向会员反馈已购买商品的信息。
A)业务建模
B)分析
C)需求
D)设计
7.以下描述最可能对应于软件开发中的哪个工作流?
某集团向优马神州经理提出举办讲座的请求后,经理根据请求决定请哪一位专家,并拟定讲座计划,交给组织工作人员执行。组织工作人员根据经理提供的专家资料通过E-mail、电话等各种方式联系专家,和专家商议讲座的时间和主题。
A)业务建模
B)分析
C)需求
D)设计
8.如果问开发人员“你在做什么”,他说“我在写文档”,那么他有可能(本题可多选)________。
A)不了解软件开发各工作流的区别
B)把自己的工作简单分为“代码”和“文档”
C)认为文档就是代码的叙述性文件
D)知道“文档”和“代码”的真正区别是什么
9.以下说法和其他三个最不类似的是________。
A)如果允许一次走两步,新手也能击败象棋大师
B)百米短跑比赛才10秒钟,不可能为每一秒做周密计划,凭感觉跑就是
C)即使是最好的足球队,也不能保证每次进攻都能进球,所以练习传球配合是没用的,不如直接大脚开到对方门前
D)虽然大家都考不及格,但考58分和考42分是不一样的