首先说下什么叫“完美软件开发”,想象一下,完美的圆在现实中是不存在的,现实中的圆只能是对完美的圆的回归,但完美的圆描述了圆的构成规则,完美软件开发意义与此相同,它试图描述软件开发的规则和铁律。但既然现实中不存在,探讨完美状态又有神马意思?好,那我们再来看一个完美状态:
牛顿第一定律说:任何一个物体在不受任何外力或受到的力平衡时,总保持匀速直线运动或静止状态,直到有作用在它上面的外力迫使它改变这种状态为止。
这显然也是一个完美状态或者说理想状态,现实中也是不存在的,那这东西又有神马意义?
个人感觉探讨软件开发的完美状态,就和探讨软件中的牛顿定律一样,虽然它现实中不存在,但对现实却有着极大的指导意义。单纯想做个高手,比如Android高手什么的是不太用的上这种探讨、这种书的,但要想把握下全局,这种探讨、这种书就有点意义了。
那怎么去探讨这种完美状态?
这类书,包括《人月神话》往往是用归纳法写出来的。但这样一来就会先天有种限制:一个人的眼界经历是有限制的,而软件世界其实无限宽广,编译器和信息管理系统的差别可能比人和猪的差别还大。所以一用归纳法,又说不清楚自己结论的边界,书就很容易偏颇。所以这本书用演绎法来写,用逻辑链来推导,看过三体的可能知道黑暗森林定律是咋整出来的,但把逻辑链用在这类书里,恐怕还很少人这么干。
看几条逻辑链。这书预设了几个前提,所有逻辑链都基于这几个前提。
- 软件是一种固化的思维
- 意识指导行动
- 项目所能耗费的资源是有限的
- 重复做同样的工作会降低效率
下面列几条书里的逻辑链。
关于量化管理的:
软件是一种固化的思维 →思维的本质是概念和逻辑 → 概念和逻辑无法直接度量和精确度量 → 度量过程中需要很多的主观判断 → 以目标为导向的,以个人为中心的量化管理(相关的激励和惩罚)将崩溃 → 参照无歧义数据(函数复杂度等)的判断将成为程序员评价中的辅助手段
关于流程尺度:
软件是一种固化的思维→思维固化本质上不可能是例行公事 → 现场的人需要较大的自主空间 →软件的流程粒度需要比较大,而不能规定工作细节,手册化。→ 可以把流程等价于一种打断,从这个尺度上可以度量当前流程的程度是否过于繁重。
关于开发模型的选择:
重复做同样的工作会降低效率→预先没有对既定问题的分析和准备,会导致同样的工作做多遍→ 纯粹的迭代会导致某些预先可以发现的问题得不到处理,进而导致不必要的重复,最终会降低组织总体生产效能
关于在何处终结需求开发:
项目所能耗费的资源是有限的 → 需求如果无限扩张,会造成以有限资源做无限工作的局面,最终导致忙中出错 → 在广度上,由于软件的应用环境处在变动之中,导致需求天生有越来越多的趋势。→ 在广度上,对不做那些需求要有清楚定义。→在深度上,需求的明确是一渐进的过程。 指望在初期某一截止时间点,澄清所有需求是不现实的。但能够澄清的,没有澄清却又导致效能降低。→ 在深度上,要使需求开发的细致程度有所定义
关于设计中的正交:
软件是一种固化的思维 → 思维的固化体现为概念和逻辑的固化 → 为保证简单性,逻辑要尽可能的少 →概念要尽可能正交
当然只有这些逻辑链是不够的,还需要补充例子,对逻辑链的具体含义进行阐释。
就拿最后一条逻辑链来说,你如果相信它是对的,再去看设计和代码,就会看出许多新问题,比如:Robert C.Martin在《敏捷软件开发:原则、方法与实践》里给出过一个关于门的例子。
Robert C.Martin的例子说:在安全系统中,有一些门,这些门可以被加载和解锁,并且知道自己是开着还是关着。
class Door
{
public:
virtual void Lock() =0;
virtual void Unlock() =0;
virtual bool IsDoorOpen() =0;
};
接下来,一种更高级的门出现了,这种门如果开着的时间过长,就会发警报,这种门被称为TimedDoor。
因为要定时出发某些事件,所以TimedDoor要用到定时器,而定时器的基本创建机制是:
class TimerClient
{
public:
virtual void TimeOut()=0;
};
class Timer
{
public:
void Register(int timeout, TimerClient* client);
};
任何TimerClient都可以向Timer注册自己,而Timer则会按照指定的时间间隔来调用TimerClient的TimeOut()。
到现在为止,Timer、TimeClient、Door在概念上是正交的,没什么问题。
接下来,为了使TimedDoor具有定时发警报的功能,这三个概念要产生交互了。
处理方法可以有很多,第一种方法Door从TimeClient继承,这种方法的正交程度最不好,接触面过大,像Robert C.Martin在书里说的,很多Door根本和定时不定时没有关系,但一旦让Door从TimerClient继承,那就不管什么门都有了定时的特征,这种关联毫无道理。
第二种方法是让TimedDoor分别继承TimerClient和Door(多重继承)。Robert C.Martin认为自己会优选这个方式。
从正交的角度看,在这种方式下,TimedDoor只和与自己有关的部分产生关联,正交性已经非常好了。
如果仔细想想,就会发现Robert C.Martin的第二种方法其实还是有问题。
门是否计时报警是一个功能,是否能录像也是一个功能,是否能自动发消息也是一个功能。
这些功能甚至可能是动态配置的,如果都用多重继承来解决,那会衍生出各种各样的对象,如:VideoDoor,TimeVideoDoor,MessageDoor,TimeVideoMessageDoor等等。这好像并不是什么好事。
这意味着正交的程度也许还是可以提升。
如果不让自己的思维局限于所有东西必须都是对象,那么就可以找到其他解法。我们可以认为定时报警功能是门的可组合部分,是使用关系而不是继承关系。也就是说,并不认为应该独立存在着TimerClient这样的类,而认为这是一种偶然的组合。否则的话,XXClient这样的类会漫天飞。想象一下,门、马桶等都可以是TimerClient,也可以是Motor的Client。
上面就是书中部分对正交的讨论和分析,这类讨论和分析会针对几乎所有主要软件开发的领域展开。好处是似乎可以多想到,多看到一些别人没看到的东西,坏处是这样一来很多地方会有点抽象。所以总的来看,这书适合愿意琢磨事,愿意思考本质问题的人,不适合喜欢做事,不喜欢思考的人。
除了用演绎法来重新解构软件开发之外,这书还做了的一件事情是:探讨软件开发各个领域间的关系。做软件的都知道,管理好≠项目结果好,流程好≠项目结果好,开发模型≠好项目结果好,设计编码好≠项目结果好。但一实际操作起来,负责不同事情的人,总是会起冲突,做流程的和做现场编码的总是捏不到一起去,因为不同部分间一方面是配合协作,一方面则是共同竞争有限资源。而为了配合好,显然任何一部分都要停在某个程度上,这个也比较抽象,是这个书另一个探讨的地方。
再写下去就太长了,书的说明就此打住。
最后说两句其他的。
看过我别的文章的人,应该大致知道,我比较喜欢写本质的东西,喜欢用一种哲学思辨的方法来看待东西。从立刻有用的角度看,其实这类文章和书挺差的。但我有时候想《人月神话》也不是立刻有用,也还许多人看,所以可能这种对本质的思考还是有用的吧,所以就还是坚持把书写出来了。
接下来会写点怎么把书写出来的东西,算是给想写书的做点分享。
--------------------------------------------------------------
理想流 + 软件 = 《完美软件开发:方法与逻辑》
理想流 + 人生 = ??
理想流 + 管理 = ??
理想流 = 以概念和逻辑推演本质,追求真理。