名可名
作者使用工作日常的交流场景表述我们应该如何准确清晰的定义一个概念,其主要关键点总结如下:
1、详细准确介绍使用方法
2、不要有模糊的操作概念,应该针对的具体操作
3、讲清楚为什么使用A而不使用B的理由
需求分析的中心思路
所以,如果我去做需求分析,我的工作首先不是记录对方的要求,而是去理解对方的工作模型。我经历过太多的情形是,对方给我说完他要的东西后,我给他的解决方案完全不是原来的方案了。
比如有人要求过我做“填写单据并打印”,最后我给他做的是“自动从数据库生成单据并打印”;有人要求我做“压缩目标文件系统提升加载速度”,最后我给他做的是“让目标文件系统可写”。有人要求我做内存压缩,最后他接受我的意见,直接加内存去了。
需求实际上是一种设计,不存在不进行设计的需求分析。我要去北京,你决定给我做一辆单车,我的需求就是在路上如何露宿的问题, 你决定给我做一架飞机,我们要讨论的是停机坪和市内接驳的问题。没有设计,你惟一能做的是背景调查。背景调查是不足以形成可实现的需求的。
所以需求分析不是需求记录,需求分析是背景调查,然后基于背景调查进行建模设计,然后才确认功能需求,性能需求,签字不能保护你,领导认可也不能保护你,正确的需求分析是对业务模型和利益模型的正确认识的过程。
欣赏架构设计的基本逻辑
架构设计的目的是为了软件将来的发展
阅读作者的文章,越来越感觉作者阐述问题清晰的逻辑,层层推进,一步一步逼近最后的目标,如此的思维方式令人叹为观止。
首先,表明软件架构的目的是什么?
如果软件不需要修改,不需要发展,“能跑就好”的逻辑是没有任何问题的。一切架构设计逻辑,都是为了未来,而不是为了现在。用现在能带来的好处来为架构设计行为辩护,都是无力的,好的架构师不能用这个逻辑来为自己的设计做辩护。
然后,说明软件不断迭代发展带来什么样的困难?
为未来又为的是什么呢?我们发展软件,是为了能力的增强,能力的增强,就带来了逻辑的增加
软件发展,或者说逻辑量的增加,带来两个变化:一个是软件能力的增加,另一个是软件复杂度的增加, 从我们想得到结果上来看,前者是个好事,后者是个坏事。后者是熵增的过程,熵增带来软件的死亡,熵增超过人脑可以控制的程度,这个就不再是有规律的系统,而是个混沌的系统,混沌系统完全不可预期,不可控制,这个系统对想控制的人来说,所代表的就是死亡。
最后,道出软件架构需要做什么以及架构的必要性?
我们要延缓软件的死亡,就要降低熵增的进度,保留中心机体的活性。从这个角度上来说,开发的工作目标是“增加”,而架构设计的工作目标是“减少”。这和人的成长很像,你把睡觉的时间都用于工作,你的收入一定会增加的,但你很快就死了。架构设计的目标就是在完成软件能力的提升的同时,减少熵增。我们愿意花工作以外的时间和精力去健身,去养生,去吃补品,目的都是降低自身的熵增过程。
但逻辑量增加本身就是一种熵增,禁止熵增的唯一方法是不增加功能,这个不能作为架构控制的目标。所以我们只好退而求其次,把我们的目标设定为:在完成功能的同时,对系统增加最少的依赖。我们欣赏架构的好坏,一个基础的判断逻辑就是这个:如果我们承认我们有共同的设计目标,优美的设计创造更少的依赖。
如何判断软件架构的好坏?
从这个角度来说,我们欣赏一个构架好不好,或者我们自己判断我们的一个设计是否合理,基本逻辑就是:它为了解决一个问题,到底增加了多少逻辑,是否有多余的逻辑,布置在其中而不自知。
“用最少的依赖解决必须解决的问题”
让代码变立体
本篇有很多的不理解之处,留存记录,摘录一些关键内容,以后慢慢消化。
软件很多概念空间的化简,都基于这种技术,比如分层
面向“角度”的编程
在编程语言可以解决这个问题前,现在真正能把代码立起来的,就是架构设计文档了。
从这个角度来说,我们根本就不应该像代码一样维护构架文档,让它变成一个不断被修改的对象,这样得到的架构设计文档就是平的,和我们想解构的代码一样。我们需要它是立体的,就需要把构架文档分层,和分版本。就是说,我们就不应该认为构架设计文档是和代码一样升级的,我们是通过写新的增量设计文档,来描述我们如何升级原来的设计,而之前版本构架设计,仅仅应该作为第一层模型来使用,并仅仅做一些Bugfixing的修改。
生成优秀的架构
作者在文章中将软件架构过程与人的成长过程类比,得以说明如下道理:
优秀的架构不是来自优秀的定义,而是来自优秀的发展。
这如同一个人的成长,不是来自优秀的教育和策略,而是来自丰富的际遇和经历。
通过教育得不到最优秀的人才,人才是通过现实打磨出来的。因为我们谁都控制不住现实,能够贴得住现实,而且运气好的,才能活下来。我们不断寻找最佳实践,并一再防止熵增,最终的目的是为自己留下活性去应对变化,但每个人的活性都是有限的,当变化过于巨大的时候,我们就要死。即使你天天保养,小心做人,遇上个地震,你也可能活不下去。
软件是一样的,我们用一切手段去控制熵增,但如果变化太大,我们的架构就会崩溃,所以控制熵增是架构控制的基础,不控制熵增是自己作死,但不作死不表示你的架构最终成功。你需要有意识地让你的架构的特定的应用场合中打磨,增加逻辑,同时保证它在这种逻辑增长下持续控制熵增,让他在这种危险中活下去,如果它最终能活下来,就会成为一个优秀的架构。
所以,架构是一个生成的过程,不是一个设计的过程。这和培养人是一样的。
分支要领设计
Git极大降低了拉分支的成本,但拉分支的成本从来不在分支管理工具上。
分支的数量是个很让人头痛的问题,因为它是个两难问题。
增加分支会增加工作量,比如修改Bug需要合并到所有的分支中;减少分支会增加设计难度,因为需要将不同的特性融合到同一个分支中去。
所以,我的设计原则是“道法自然”,让这个分支序列自己生成。方法是:
- 一开始就只有一个分支,全部人力都在这个分支上
- 谁都可以要求开分支,但需要解决两个问题:
- 2.1 谁来提供人力来维持这个分支(本质上市场收益是否能支持这个分支的投入),这个人力是否足够
- 2.2 为这个分支定义一个Topic,然后证明这个Topic和现有的所有Topic有足够的不同。这同时也定义了这个分支的生命周期。
- 考虑手段把这个分支的有益修改收回到主线分支上
在整个分支设计中,架构师的职责在如下两个方面:
架构师在整个决策模型上就必须卸掉这个错误的用力方向,让决策面对市场和收益。 所以,首先是研发和市场两股力量冲突:多少投入可以赚回多少钱。而分支,正是整个问题面对的第一个决策。
架构师真正的私货是最后那个决策,因为那个动作对谁都没有直接收益的,它保证了整个组织向前进,所有的解决现在问题获得的经验,最终变成组织存在下去的动力,为组织不断上升提供支持。而其中的控制者,圣人,通过组织的上升达成自己跟着上升的目的。这就是所谓以其无私,所以成其私。
最后,作者总结分支设计要领,“每个分支有各自的特性和功能以及不同的分支可以有不同的质量”。
分支是今天大型软件构架设计中首先面对的问题,如果你不首先定义好你的分支模型,很多研发和市场的讨论就会聚焦到“功能”和“特性”,不谈“分支”的功能和特性都是耍流氓,这大部分情况是失去发展能力的开始,架构师需要非常慎重。
另一个方面,展开了架构分支,我们需要面对另一个常见问题,不同分支的质量要求是不同的,你见过很多产品经理或者质量经理要求每个分支都达成相同的质量目标, 物或损之而益,或益之而损,不是越多越好的。我们永远面对的不是“道理”,而是资源和目标之间的妥协。
怎样做项目管理
项目定义:
项目是既定的资源和要求的约束下,为实现某种目的而相互联系的一次性工作任务。
项目管理概念:
项目管理同样如此:我想在要做一个软件了,无论你如何设计,反正人就是这些人(当然,这是个动态的东西),找一个办法,让项目按质按量顺利完成,这就是项目经理的道。
项目管理难处:
项目管理千头百绪,事前的预估,过程的定义,甘特图的管理,关系网的建立,当知心大姐,当鼓劲领袖,当拿鞭子的监工,等等等等,不一而足。所以这才让很多人抓不住重点。
项目管理的宗旨:
相信可以解决问题的东西,不要相信概念本身。所以那个“项目”的定义才这么重要:你管控一个项目,不是为了满足PMP的那些方法论的,是为了实现项目目标的。那么你项目筹码就那么多,怎么能用这些筹码换你的那个结果?
项目经理核心工作:甘特图(WBS, Work Breakdown Struct)和风险控制。
WBS(Work Breakdown Struct)可以是任何形态,你写在笔记本上,用MS Project画图,还是用Excel一类的工具写成一个列表,都无所谓,工具对很多问题有帮助,但不是问题的核心。问题的核心是,你做任何长跑,都不会拿终点作为目标,所以你肯定是要分阶段的,如果你的工作依赖特别复杂(比如做一个数据中心的建设,这涉及采购,招标,申领牌照,开发,部署等工作),用一般的任务列表很难管理好,这种情况能画甘特图的软件能帮上很大的忙。其他的如小型的软件开发项目,常常是几个大迭代组织一组小故事的,基本上用任务列表就已经能管理得很好了。
相对任务的划分及安排,作者更加强调的是风险管理:
很多人望文生义,把风险管理看作是加花的一部分,认为只是项目管理逻辑中其中一个(和很多其他方面并列的)方面了。却没有搞清楚,风险管理其实是整个项目管理工作的中心。我们需要一个项目经理,很大程度上是因为我们需要有人去管理所有的风险。因为项目最后没有按质按量完成,都是因为当初对WBS的假设有误,我们要守护WBS,就是提前发现WBS的破绽,然后把这个破绽消除掉。
当项目经理和架构师是同一个人时,面临如下风险:
不少小组织,项目经理和技术专家(带头人)通常是一体的,原因就在这里,因为项目经理就是打杂的,如果单独养,根本养不起(战功不能和投资匹配),但项目管理是个专职的工作,基本上,如果你管理一个10人以上的团队,而且已经有了特定的交付目标,把核心技术人员(比如架构师)和项目经理合体,这个人将同时做不好项目管理和架构师两个工作(即使这个团队自组织能力极强)。
人一多,时间一长,一起做一件事情,会有无数的风险:张三母亲病了,突然请假;李四找到了更好的工作,新人没法理解接手他的工作;关键的一个开发板从香港入关的时候不符合规定被海关扣下了;合作伙伴突然被人收购了,走了不少人;国家突然出台新规定,软件需要找广电认证;某个技术难度太大,根本搞不下来;项目拉得太长,投资人失去信心,取消项目;……回忆一下你失败过,延期过的项目,它到底是怎么失败,怎么延期的?把这个问题想清楚,你才会正经地对待风险管理。
作者更重要突出的是一类永远存在的风险:对设计目标和工期预判错误。
有人以为技术专家会比对技术理解不深的人(比如以管理为主的项目经理)能更好预判一个技术工作的工期。这完全是自欺欺人,开发过程序的,你们发自内心预判一下你自己对一个模块的开发工期的判断准确度有多高? 基于技术来预判工期,远远不如基于项目管理经验来预判工期。而解决技术问题和预判工期根本就是两个维度,放在一起考量,基本上就是错误的开始了。
项目经理不是那个做好计划就开始指手画脚的人,你看见他在拿鞭子抽这个敲那个,但实际上他脑子里每天都盘算着,“这个任务如果再延期下去,我就要停掉那个任务,补人进来充实这个任务了”。这是整个软件工程成功过程中,一个独立,必须,工作量巨大的工作,想靠管技术的工程师“顺便干”这个工作,和让写Java Script的工程师顺便去做个PCB板没有什么两样,根本就定不下心来
程序员,架构师,项目经理因各自职责不同,获得成功的阶段也不一样:
程序员实现一个模块,立即能感受到运行和成功的快乐。架构师?那得等产品成功以后才能体会到快乐的事。项目经理一样,谁不想立即看到一个程序或者一个模块啊?但项目经理的快乐是要等项目成功以后才能评判的。
终极解决方案:
回到风险管理,要把项目挑上身,风险管理有三个要领,是每个项目经理需要掌握的:
- 风险识别不来自项目经理,风险识别主要来自WBS任务的执行者,要用软件工程师收集需求的心态去识别风险。要要挟他们如果“搞不定我就杀你全家”这样的情怀把可能的风险逼出来。
- 为每个风险设定规避计划和应急计划。特别是应急计划。很多项目经理即使管理风险列表,也不好好准备应急计划。或者干脆搞不清楚规避和应急计划有必要区分。
我是强行要求我的项目经理给应急计划的,因为只有你有应急计划,你才真心认为这个事情是个风险(而不是个延期的推脱理由),很多风险都是有一半几率会真的发生的,发生后会不会对你的项目造成致命的影响?你还罩得住不?这个才是问题的核心。
看一个项目计划中有没有风险应急计划,很多时候就能判断这个项目经理到底是不是足够专业了。(我不怕告诉你这个,就算你拿这个骗我,背不上身的人做出来的应急计划一样是一眼能看出来的) - 在执行的过程中,要始终基于风险管理来管理WBS,不断响应变化。有了项目经理,技术或者业务为中心的成员(我不管这些人在组织中的地位是比项目经理高,还是比项目经理低),才有可能有效输出