软件项目复杂性

1.技术架构与框架

Reuse is about people and education, not just architect.  -------- 《97 Things Every Software Architect Should Know》

认为设计优良的框架,细致考虑并精巧实现的架构自然会被人们重复利用。事实上,即便是最精美,最优雅的框架,可复用性最高的系统,也必须满足下面的条件才可能被复用。

(1)大家知道它们存在。

(2)大家知道如何使用它们。

(3)大家认识到利用已有资源好过自己动手。如果大家找不到可复用的资源,或者不知道如何使用这些资源,人的天性就会发挥作用。他们会自己动手实现。

反思我们设计框架与组件的团队,是否满足以上原则,不满足实际是不成功的。

2.项目进度

更多的项目之所以没有被宣布为失败,很大一部分程度上是因为项目的实施者(或者用户)接受了充满缺陷的成品、同意追加了成本或者延长项目交付时间,软件工程中的时间黑洞永远让人无法看清其本质。

前人总结:

Adding human resources to a late software project makes it later.   ---《人月神话》


Maximize the velocity and volume of information flow.   -------How google works


提高开发效率,一些非技术因素:优秀的团队总是能额外产出大量的文档,并经常组织内部分享。


3.​​Cynefin​​框架

是由​​Dave Snowden​​在知识管理和组织战略中提出的一个概念框架,用于辅助领导者认知问题并进行决策。

软件项目复杂性_架构设计

简单问题Simple:不言而喻

如果一个问题的因果关系非常明了和单一,则这个问题就是一个简单问题。大家对于这个问题的原因有着统一的不言而喻的理解,这个问题的发生原因非常的确定,几乎没有什么变数,即“知道的知道”。

比如,在一个炎热的夏天回到家里,发现房间里也被太阳晒的热烘烘的。这种情况下,我们几乎不假思索就会打开空调,房间立马就凉快下来了。所以对于房间很热这个问题而言就是一个简单问题,可以迅速的找到解决问题的方式。

简单问题,一般的处理方式是:了解-归类-响应。

归类是人类最擅长的处理问题的方式。当遇到一个问题时,首先我们会将这个问题在自己的大脑中进行快速检索,如果这个问题被大脑判断为是一个熟悉的问题,那就调取相应的经验库并在这个经验库中找到匹配这一类问题的答案。这个“类”就是所谓的pattern,它是人的大脑在经验积累的过程中不断对问题进行抽象、分解、简化而形成的。因此,简单领域的问题一般也都会有一些最佳实践。

但是在这个问题域需要警惕落入思维范式的陷阱。大脑在思考问题的时候往往是很偷懒的,本着能不思考就不思考的原则,有时候会拿着pattern去套问题,不管这个问题是不是真的能够被归类。部分大企业管理者经常会通过做冥想来回顾一整天所做的决策,就是为了避免落入思维范式的陷阱,提醒自己不要被偷懒的大脑所蒙蔽。

繁杂问题Complicated:专家意见

和简单问题不同,一个繁杂问题的因果关系往往不是单一和清晰明了的。也就是说,一个繁杂问题可能是由多个原因造成的,并且这些原因并不直观。相比于简单问题可以依赖经验库快速检索、归类找到答案。繁杂问题往往没有经验积累,无从归类。所以遇到这类问题,需要进行分析,即:了解-分析-响应。

一个典型的繁杂问题的场景就是Debug。在生产环境上报出bug之后,开发需要进行问题复现、审查代码、调试、根因分析等等一系列动作之后才能找到原因,而且可能还不止一个。

奔驰车主发现发动机异响后送修4S店,技师进行拆解找到问题,更换零件最终修复。这个问题也是繁杂的,一开始包括技师在内谁也不知道为什么发动机会有异响,是在一层层拆解,打开发动机,找到破损零件之后才定位到问题。这个问题原因的追溯是需要分析过程的,因果关系不是显而易见但是确实存在,即“知道的未知”。这是繁杂问题的特征。

前面说到,繁杂问题一般是新的知识领域的问题,没有经验积累。但是注意,经验是依赖于人的,是相对主观的。也就是说同样一个客观存在的问题对于不同人而言可能是不同域的问题。比如,车辆故障对于刚入行没多久的技师而言是一个繁杂问题,但是对于工作了10多年有丰富经验的技师来说这个问题可能就显而易见,是一个简单问题。所以在这个领域,专家意见尤为重要。

复杂问题Complex:事后方知

复杂问题的因果关系是事前不可预知的,这个因果关系是不稳定的,即“未知的未知”。这种情况下,解决问题往往没有标准正确答案。

复杂问题跟繁杂问题的区别就像是由零件组成的汽车和由人组成的团队。汽车构造虽然很繁杂,但是拆解之后还是能原样组装回去。任何一个零件的破损可以预测会导致什么样的问题产生,它虽然繁杂但却是一个稳定的静态结构。而团队则不同,人的行为难以预测,更别说团队的组织行为了。团队是一个动态的整体,其中某个队员的一个行为,我们难以预测会对整个团队造成什么影响。

典型的场景,比如在进行团队retro的时候发现这次生产环境无法登陆的问题,可能追根溯源是某个开发在部署的时候配置文件有误造成的。但是为什么这个开发会把配置文件搞错,是因为粗心?还是流程不到位?甚至有没有可能就是这个开发被个人家里的事情所扰,工作状态不好才导致这个问题的呢?即使采取改进措施解决了这次的问题,能否在以后杜绝该类问题的发生?我们发现这里有太多的不确定性。

于是解决复杂领域的问题,就不能单纯靠​​还原论​​的解题思路。一个复杂的动态系统整体远大与构成该系统的各个部分之和,同理一个动态系统的问题也不能单纯通过分而析之的方式来解决。

解决这类问题的思路是:试探-了解-响应。

如果可以进行“输得起”的试验,指导性规律就会浮出水面。正是出于这个原因,不必冒进试图采取一系列行动,而是要耐心等待前进的道路自行显露。首先须探寻,然后了解情况,并做出响应。也就是说,这时候的解决方案是经过不断试探之后“​​涌现​​”出来的,而非精心设计出来的。


混乱问题Chaotic:莫名其妙

如果一个问题的因果关系不可知,完全无法了解问题发生的原因,或者问题的原因太过多变,那么就属于混乱。这个时候,寻找问题答案已经变得没有意义,首要任务是及时止损。迅速采取行动,尝试将所处领域转变为其他领域。

这些问题常见于一些突发性的社会问题,比如汶川地震。在混乱的局面下,及时果断的采取行动,尝试建立秩序变得尤为重要。尝试从混乱转变为复杂问题。

归纳总结一下各个领域之间的区别。

软件项目复杂性_生产环境_02

希望对大家项目管理有帮助。



如有想了解更多软件设计与架构, 系统IT,企业信息化, 团队管理 资讯,请关注我的微信订阅号:

软件项目复杂性_生产环境_03

作者:Petter Liu

本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 该文章也同时发布在我的独立博客中-Petter Liu Blog。