在平时的软件设计中,我们会对业务进行分析,并进行建模,最后输出设计文档,以便于开发人员编写出高质量的代码,但即使无论用何种方式设计,总是难以产生高质量的代码,本章将会向你揭示其中的原因。
其实设计可以认为是对业务进行量化、数值化的过程,就如同对声音进行采样、量化,最后变为数字。但在设计阶段对业务进行数值化时,必定会有噪声或是失帧,好的设计只能降低噪声与失真的频率、概率,但不能完全消除。(这就好比手机通信)但是往往就是这个原因,使其噪声与失真被带到了编码环节,并被无限放大,最终导致产生不了高质量的代码,下面我将举例说明:
在上图中,业务人员提出“有效用户”,而在设计阶段被量化为“用户状态为激活”,最后变为代码:user.status=1,如果需要在别的代码中判断此用户是否激活,则会写成如下代码:
代码1
User user =getUserByID(id);
If(checkActive(user)){
………….
}
如果哪天业务人员说开户用户也是有效用户,那灾难就来临了,你需要在所有调用checkActive()方法的代码中进行纠结,到底是改还是不改,因为有可能部分代码执行条件只能是激活而不是开户。如果此checkActive()方法调用的地方越多,你所花费的时间就越长,而且还不一定能够修改正确。
因为在设计阶段,把业务“有效用户当前认为是激活用户,但今后可能会发生变化”直接量化为了“有效用户=激活用户”,将“变化”这部分内容给过滤了,即产生了失真。
如不失真,则会写出以下代码:
代码2
User user =getUserByID(id);
if(checkEffectiveUser(user))
………….
}
如按以上代码,不管业务如何变化也不需要纠结了,但在失真的情况下,开发人员很难会写出上述代码,这完全取决于个人的觉悟程度。
下面我再举一个噪声的例子,请看如下代码:
代码3
User user =getUserByID(id);
If(user ! =null
&&(user.getStatus() == 0
|| user.xxx=xxx
||user.getStatus() ==1)
){
……
}
其“有效用户=开户用户或 激活用户”这一信息被其它判断条件干扰了,即存在噪声。而且产生上述的原因可能就是因为在某张流程图中就是如此描述,故当业务变化时,开发人员需要先找出失真的部分,或去除噪声。其唯一的方法就是向一个靠谱的业务人员了解业务,以获取完整的信息,这也从另一个方面说明精通业务对于程序员是多么重要。
原先设计的目的就是为了编写出符合业务需求的高质量代码,但其实现在我们对好设计的评判标准是此设计能否使编写出的软件符合业务需求,即设计是否对业务描述正确,或者说设计只是对上负责(业务)、而不对下负责(编码),以至于设计与编码之间严重脱节。
好的设计是可以编写出好的软件(即满足业务需求),但其软件的代码质量不一定高。个人认为好的设计应可以做到:能使任一开发人员基于设计编写出符合业务的高质量代码,而与其开发人员的能力、经验无关。
比如当业务发生变化时,无论是菜鸟、高手,对业务是否熟悉,其能够正确的确认需修改代码所花的时间不应相差太大,应在一个数量级别内。
好的设计应同时对业务、编码进行负责,否则编码质量难以控制,但现实中这样的设计可望而不及,下面我将提出一种新的设计方式,可以达到一石二鸟的目的。