说起软件设计,我们可能每个人都做过,但是什么样的方案才是好的设计方案?如何才能设计出一个好的设计方案?在设计过程中需要注意哪些呢?不要总是说:低耦合、可维护性、可扩展性、简易性、可重用性等,本文试图另一个角度出发,带着前面的这些问题,使大家能明白那些问题的答案,并与大家一起探讨。
什么样的方案才是好的设计方案?
当我们完成了一个良好的设计方案后,我们回头再仔细分析是什么因素影响了我们的思路,使我们最终完成(确切的说是选择了)了这个设计方案(而不是另一个),我们会发现这些因素是:用户功能性的需求、技术性能上的要求和研发成本(或能力)的制约,当然其实还有一些其它因素如:客户主观上的要求、审美或商务因素、向前兼容性要求等,不过这些因素多半是一些非技术性因素,我们在此不做过多讨论;能否很好的满足这些因素就决定了一个设计方案是否是一个好的设计方案,所以我们在设计之初就必须对这些因素加以充分的考虑。
如何才能设计出一个好的设计方案?
但事实上,基本上没有一个方案是可以每个因素都能***满足的,一个好的设计方案,往往是一个平衡的结果,这也是为什么我们在讨论设计方案是总是可能争论不休的原因,因为不同的人从不同的角度出发都可以得到他认为好的一个方案,人们总是会有各自的理由,而且那些理由都是有道理的,但请大家记住:一个好的设计方案,往往是一个平衡的结果。从某种意义上说能否做好平衡是决定一个方案是否是好的方案的关键,尤其是对那些复杂的大的设计方案。
平衡的艺术
但怎样才能做好平衡呢? 答案显然不是:“ 一碗水要端平 ” 。有一个著名的原理叫 28 原理,它同样也适合我们软件开发的规律,我们的百分之 80 的精力设计和开发的部分只给我们带来了百分之 20 的回报,或者说,我们百分之 80 的回报只是我们的百分之 20 的努力得来的,这个原理告诉我们,我们在平衡时要抓住重点,那些非重点的部分,如果必要可以舍弃,舍弃它们可能会带来更大的价值。下面我们先分析一下前面提到的几个关键因素来仔细讨论下平衡的艺术。
用户功能性的需求
毫无疑问,我们的软件最终的目的就是为了要满足用户的需求,由于我们要设计的是一个产品型的软件,这就决定了我们的需求不是很好明确,面可能比较广,甚至有些需求可能还是我们自己想象出来的,但正因为如此我们才有平衡的必要,试想如果我们做的是一个项目,那只需要按照甲方的要求完成即可,合同上甚至很明确要求了,此时也没有多少需要平衡的了。一个产品型的软件,要把百分之80 以上用户都用的功能进行良好的设计做到易用好用性能出众并投入大量人力研发,而那些 50% 用户会用到的需求就可以少投入些人力与时间,那些百分之 5 用户才可能会用的功能且需要耗费大量人力时间的甚至可以舍弃不做。
但平衡也不仅仅是在与选择做与不做某个功能,更在于怎么做某个功能,一般对于用户的需求我们会有下面几个实现方式:
1 实现一个简单易用、设计良好、100% 满足用户需求的界面或功能
2 通过一些界面上的选项设置来实现用户的需求
3 通过手工修改一些配置文件来实现用户的需求(这种实现方式可能需要的研发资源只占***种实现方式的1% )
4 通过脚本来实现用户的需求
5 通过插件或定制开发来实现用户的需求(后2 种方式其实就是说现在不考虑这个需求,以后就算有了我们能支持即可)
不同的实现方式需要投入不同的量级的研发资源,从上至下占用研发资源越来越少,这就是我们需要做平衡的地方。
技术性能上的要求
用户总希望在软件界面上执行任何操作都能立即得到结果、希望系统能支持越来越多的在线并发、希望系统能全年不停机运行不出任何错误,希望系统能兼容各种平台…… ,所以对我们的系统有很多性能上的要求,要求我们必须支持集群、各种高速缓存、多语言、支持事务操作等,有些性能要求是必须在设计之初加以认真考虑的,因为从以往的经验来看,如果出于研发成本的考虑,系统一开始没有考虑集群、多语言、事务,而在以后系统成型后再予以考虑,那会往往付出更大的代价,这种代价有时是伤筋动骨的。
同样是满足用户功能上的需要,一个实现需要投入大量研发资源,但程序效率很高,而另一个只需要少量的研发资源,但程序效率稍差,此时该如何平衡呢?相信大多数人都能做出正确的选择,要综合考虑:目前可用的人力资源数量、需要投入的研发资源的差异,模块的使用频度的因素;我经常说,对于客户端应用来说在用户的一次界面操作中只执行一次的函数就可以少花点时间实现,因为3ms 完成一个操作的执行和 300ms 完成一个菜单的执行其实对用户来讲是差别不大的,但这个并不适用与服务器端应用,服务器端应用还需要考虑到在线人数,如果能 3ms 完成就能支持更多的在线用户。
研发成本(或能力)的制约
这个因素往往是我们最应该多考虑,但是经常缺忽视的一个因素。
以一个工程师一年开发3 个模块和一年让他开发 10 个模块来做个比较,只开发 3 个模块时,他基本上可以做到让每个模块完成到 90 分以上,包括代码质量、测试单元、文档等,还能有些时间学习和研究些新技术,并能保持一个愉快的心情高效率的工作下去;但是如果一年让他开发 10 个模块,他可能只能勉强做到让每个模块完成 60 分以上,代码可能有考虑不周全留下隐患、测试覆盖率不高、文档欠缺,终日忙于赶进度没时间充电,工作疲惫效率低下。
多半的研发工程师是乐观的,在开始的时候自信满满,过低的估计了研发需要的时间,我经常说,要把一个模块完成到60 分可能 1 个人月,要完成到 80 分可能就要 3 个人月,要完成到 90 分以上可能需要 8 个人月,这个增长的比例并不是直线性的而是抛物线形的,所以研发周期往往难以估计,我们必须为将来准备足够的缓冲时间,某种意义说,越多越好。
所以这也正是在上面的一些平衡过程中,有一些因素要让位于研发资源的投入的重要原因,一个为将来的研发困难做好了充分准备的设计方案才能算是一个好的方案。
在设计过程中需要注意哪些呢?
从需求出发
从用户角度理解的需求出发考虑总是没错的,最忌设计时只考虑技术方面的问题,当然技术方面的问题也必须予以考虑,但前提是必须对需求***充分的了解和分析,从需求出发并不是说需求***,需求有时也必须让位于其他的一些因素,要做好平衡。
从一开始就考虑那些影响面很广的技术要求
这些因素很可能严重的影响设计,必须提前予以研究,这种研究可以是脱离需求的零散的,有时甚至可以写一些测试代码,但最终必须还是从需求出发,在充分的了解了各种技术点之后,再决定自己的最终设计
充分考虑研发资源成本
再好的设计没有付诸实施的资本也不行,所以还是那句话,要做好平衡。
【编辑推荐】