企业定制软件开发不是计算机科学,需要解决的不是编译原理也不是组合数学。那么,企业定制软件开发的核心问题是什么?
越来越感觉到,从事一个领域不需要有特别深刻的理解,但起码要知道做这个领域的事情,需要解决的核心问题是什么。比如说,开发C/S结构软件,状态同步(C/S状态同步以及窗口之间的状态同步)就是核心问题之一,而开发B/S结构的软件,状态同步就不是那么核心的问题。如果事先知道需要有这些核心问题需要考虑,在日常应对接踵而来的具体的事务的时候,就能够把解决问题的层次抬到更宏观的层面。
目前而言,个人感觉企业定制软件开发的核心问题有两个:
1、如何保证所有参与者(包括客户在内的开发团队,以及最终用户)的沟通强度,使其能够满足完成开发目标的需要
2、如何管理企业定制带来的软件自身内在的高复杂度,使得复杂度不会超过团队的维护能力范围
在前面一篇中,谈到了核心问题中的{dy}个,沟通强度问题。团队而言,刨去个人能力,最重要的就是人与人之间的沟通。没有好的沟通,即便团队的个体能力都超级强,也无法形成合力。但只要有好的沟通,至少可以做到人尽其用。假设一个标准人的生产力是1/day。某些特别强的人可以达到3/day。但是如果需要达到10/day的生产力才能在市场允许的时间下完成项目,那么就无法用一个人来完成之间事情,所以才会有团队存在的必要。但是有两个标准人,并不会达到1+1=2/day的生产力。可能只有1.5。有三个标准人,更加不会达到1+1+1=3/day的生产力,很有可能有1.8。那么是什么制约了团队的整体生产力,那就是沟通。当两个相关联的任务A和B是一个人做的时候,关于任务A的知识存在于左脑,关于任务B的知识存在于右脑。那么结合两个任务的知识把其组装起来的沟通效率就是大脑内部的电信号的速度。但是如何任务A是由Dev甲完成的,任务B是由Dev乙完成的,那么整合两个任务的效率就受到人嘴皮的震动频率的约束,受到表达能力的约束,受到理解能力的约束。有人研究过,两个人即便是面对面,传输的比特率也要低于最早的拨号式Modem。更不用说,有的时候开发团队是分布式的。在无法看到表情,肢体语言,无法共享白板,只能在越洋电话里听到声音,而且其中还有一方是非工作时间,在这种情况下,1+1几乎很难达到1/day的生产力。什么是高效的团队,就是能够让1+1的值尽可能大的团队。如何变得高效,让沟通变得更加高效。怎么样让沟通变得高效高强度?这就是我们要处理的核心问题。
{dy}个问题可以应用于所有的人的团队行为之中。人只要聚集成群,就会有沟通问题。所谓,有人的地方就有江湖。第二个问题则特定于企业定制软件开发。对于互联应用开发,也许复杂度的管理是其次的,最需要关注的是大用户量下的可扩展性。但是对于企业定制软件开发,由于业务自身的复杂度,导致了定制软件的复杂度。特别是业务的组合,导致的组合复杂性。假设在理想情况下,一个系统可以分解为模块A,B,C,其复杂度都是2。在复杂度管理良好的情况下 ,这些模块是被明确划分的,要理解A,只需要关注A,以及B与C少量与A交互的部分,也许理解的复杂度只是2 + 0.5.。但是在复杂度没有管理的情况下,所有的“逻辑”(也就是复杂度)都是随意地放置的。那么也就是没法办法保证,读A的逻辑只需要关注A,甚至这个A都是不存在的,你看到的知识一个系统,包含了A,B,C的功能,是完整的一块。这个时候要真正了解这个系统行为,可能就需要2 * 2 * 2 = 8这么高的代价了。随着模块(变量,方法,类,包,模块,Bundle)的增加,我们需要同时理解的东西也在不断增加。不去可以地管理复杂度,很有可能,我们需要了解一块功能,就需要把所有的代码都去阅读一遍。或者说,改动了一个方法,使得整个项目都需要重新被测试,因为没有地方是可以被信任的。如何管理复杂度?这就是我们要处理的核心问题。
有意思的事情是,这两个核心问题是重叠的。把人,角色等同于类,接口,都抽象地看成点。把沟通理解为人与人之间的联系问题。把复杂度也理解为类与类的依赖问题。那么沟通问题和复杂度的管理问题都是如何把这些点联上线,组成一个高效的图的问题。这个图,就是一张关于“依赖”的图。人与人之间的依赖,类与类之间的依赖,包与包之间的依赖。依赖的另外的一个名字就是Coupling。而我们追求的就是Cohesion。Coupling(耦合)/ Cohesion(内聚)这两个词的妙处在于,明白的人根据自己的经验,一看就点头。不明白的人,由于没有对应的经验,无论怎么解释,都是摸不着头脑。正是因为其“妙不可言”性,所以我可以说这两个词就是所有问题的答案(你也无法反驳)。但至少我们可以知道企业定制软件开发的核心问题其实就是一个:就是管理好人与人之间的Dependency,包与包之间的Dependency,使得信息可以在高度依赖的人与人之间快速传递(强调Coupling带来的消息传递的效率),而理解又可以局限在高度内聚的模块内部(强调Cohesion带来的维护便利),但同时又不能让某人过度被依赖倒置工作过劳死了,被依赖得越多要求其体能越好,对于包的内聚也一样,高内聚做到{jz}就是最小的编译单元(类?),又会导致包的粒度过小,使得包的数量变得巨大,失去了维护的便利性。我们需要做的,就是在To Depend or Not To Depend中,根据场景作出取舍。
那么抽象而言,无论是解决沟通问题还是复杂度问题都可以归纳为:
1、设置目标指标
2、度量现有的指标,观测现有的依赖图
3、做出依赖图的调整计划,并执行
4、观察指标的变化
5、重复步骤3,4,直到目标达到
但是问题是:
1、如何度量指标?沟通的效率?代码的质量?都很能度量。
2、如何观测现有的依赖图?包的依赖还可以观测,但是团队的协作是比较难观测的。
3、如何对依赖图做调整?重构?Change Agent?人不比代码那么容易改变。
4、如果指标不是简单数字,怎么比较?怎么知道指标是朝着目标发生变化?
这四个问题,几乎没有硬的科学问题。管理复杂系统的复杂度,可能是一门硬的科学。但是夹杂了人的因素的企业定制软件开发,一定不是一门硬的科学。那么,数学公式不是这些问题的答案。那么该朝哪个方向努力?
TO BE CONTINUED