1

软件设计(架构)往往在项目开发中起到非常关键性的作用,至少它是能够工作。良好的软件设计包含了:灵活性、可伸缩性、可行性、可复用性、安全性,通过该一系列的定义,使我们影响到了软件功能的设计和特征。

(一)、什么是过度设计

过度设计一词在英文中称为"over design",over意思是太多,design意思是设计、构思,通过教科书上面的解释,意味着你设计的或构思的太多了,即为过度设计。

什么是过度设计?设计出来的系统比恰到好处要复杂或臃肿的多,过度的封装、继承、接口或是大量的无用配置方法,其实就是用户需要一把杀鸡的刀,而你却设计出了杀牛刀或是电锯。

过度设计通常来自于开发者将问题过于复杂化或是前瞻性欠缺。

在我们日常所犯的错误中,大部分是来自于前者,至于后者的欠缺,需要一定的项目经验和洞察力来支撑,能够合理的预判和考虑需求会哪个方向发展。

在前者,问题复杂化会引入大量额外的代价,如成本上升,系统缺陷增大、提升维护成本、降低系统性能。而高性能和可维护性都是系统的隐性需求,如果这些也没实现好,那就可能属于设计错误。

但是从客观角度来看,能够进行过度设计的,多半设计能力高于设计不足的,过度的设计改回来的成本也比设计不足的改过去的成本低的多,在此需要更多地去权衡"利与弊"

(二)、过度设计案例

以系统充值为例,最初你设计的系统只需要一个支付宝功能,你的数据库设计如下:

id primary key int  //主键
user_id int//充值用户
status  int     //-1充值失败,0充值中,1充值成功
order_no string //第三方支付系统订单号
amount  decimal //金额

但是没过多久,你的系统需要接入另一个支付系统-微信,需要区分用户是通过微信还是支付宝充值的,于是你的数据库设计便成了以下模样

id primary key int  //主键
user_id int//充值用户
status  int     //-1充值失败,0充值中,1充值成功
order_no string //第三方支付系统订单号
platform string //第三方交易平台
amount  decimal //金额

但是你想了下,感觉可能以后需要接入银联支付,需要记录是哪张银行卡支付的,然后你又想了下,既然已经接入了银联支付,那顺便就再完善以下,支持国际支付,如美元充值,港币充值,然后需要记录上当地充值的汇率及当地支付时间,最终你花了一天的时间,将数据库改成了这样

id primary key int  //主键
user_id int//充值用户
status  int     //-1充值失败,0充值中,1充值成功
order_no string //第三方支付系统订单号
platform string //第三方交易平台
amount  decimal //金额
currency string  //货币:CNY USD HKD 
bank_id int //银行卡ID
rate   decimal // 充值汇率
local_pay_time  //当地支付时间

完成基本设计后,你花了4周的时间完成编码和测试,最终交付了上去,然而系统的初衷只是需要简单区分的是微信充值或支付宝充值,而因过度设计带来的额外成本和缺陷是非常巨大的,为此我们需要尽力让自己做的恰到好处并且避免过度设计。

(三、)如何避免过度设计?

避免过度设计的最佳方法就是“不要设计的太远”,未了解实际未来,就做出了各种预设和判断,为系统增加了额外的负担。

正如scrum(敏捷开发)所倡导的Evolutionary Design(演进式设计),将每一次的重构和迭代都映射和更新到最新的设计中来,从而最大限度的满足系统的功能性需求和非功能性需求。

当你手里握着一把锤子时,不要把所有看到的,都当成钉子。


Sinming
310 声望21 粉丝

Bug总工程师