需求是引起设计变化的源动力。
没有需求的变化,任何已经完成原有功能的软件在设计上,都没有变化的必要了,无论原先的设计是好的还是糟糕的。需求变化了,为什么要修改原有的设计,可不可以不修改原有设计。答案是可以的,然而为什么要修改,或者说完善原有的设计,让原有设计朝着适应需求变化的方向发展。因为原有设计不能满足软件需求变化的需要。就要修改原有设计。
好的设计是什么?
在需求变化时,只做新增代码,而不去修改原有已经存在的代码。这样的设计具有弹性--可以迎接新的需求。具有可维护性--原有代码和新代码之间的耦合性很小。原有代码中的bug,经过几轮测试之后,越来越少。bug的数量承收敛状态,逐渐趋于收敛。这就好比盖楼的时候,一层盖好了,再建第二层的时候,不用将重新加固第一层的楼的墙壁,来支撑第二层(把第一层拆掉重新盖的可能性很少)。好的设计在于只是针对新的需求,增加新的代码,而不是修改原有的代码以适应需求。如何才能做好这一切呢。
为什么要进行分析和设计?
我们从编程语言的发展开始说起,从最初的机器码、汇编到C语言,到现在的C++,JAVA。为什么会语言会这样发展??和人们对事务的认识,以及人们提高生产力的期望有密不可分的关系。计算机编程技术的不断发展,可以看出这一切。机器码写软件,对程序员的技能要求很高。是最原始的编程方式,那时候也许写一个从1加到100的函数都会经历很漫长的过程。然后有了汇编语言,这下好了,汇编的最大好处是,编程不在直接面对0101这样枯燥和易出错的编程过程,而提供了基于字符表示的编程语言。之后有了C语言。人们就可以写更大一些的软件。满足更多的需求,生产力也大大提高了。同时,也出现了软件开发的工程方法,也就是我们熟悉的结构化设计方法。但是结构化编程不能满足更大规模的软件开发。至于其中的原因,涉及到分析方法中的很多问题。主要因为结构化方法在处理现实世界中的许多问题时候很吃力。比如在面对不同两个实体之间的信息交互,并发处理等方面。还有一个原因,就是结构化方法设计出来的软件在重用方面,以及团队合作开发方面都有很大的制约。当然结构化方法也有其优点,因为现实中的实体在处理事情的中,微观下也是顺序执行的。只是随着软件规模的越来越大,这种顺序执行的粒度变的越来越小了。人们的关注点已经从这一个层面中越了过去,关注的更多的是事务之间的关系。不再是事务内部的处理过程。
当然人们需要功能更强大的软件来满足自己的需求,以不断的提高自己的生产力的时候,出现了面向对象语言。这种语言能够更好的描述现实中的事物,而且相比结构化语言更贴切。面向对象语言出现之后,随之而来的是面向对象设计和分析方法。这些方法都是为了实现更大规模的软件而出现的。软件开发在这个时期,脱离了原有的小作坊式的开发方式,出现了大规模团队开发的方式,这时也出现了软件开发的工程方法和管理方式。这个时期的软件开发不再是单兵作战,为了在更短的时间内完成更多的用户需求,团队合作被高度重视。另一方面,由于软件越来越大,代码量越来越多,软件质量也被重视起来,人们开始明白软件的缺陷发现的越早,成本就会越低的道理,所以软件开发的前期分析和建模就显得很重要了,因为这时候的成本是最低的。
无论是团队开发还是前期分析,都离不开软件的建模。有了模型大家都不再用凭空想想,沟通起来也方便很多。模型中子系统和子系统之间的交互关系,子系统内部模块之间的交互关系,以及模块中类之间的交互关系都通过对软件的建模,讨论清楚。可以想象如果,拿到需求直接写代码,写完代码之后再讨论类之间、模块之间、子系统之间的关系。结果会是如何?系统是否得到了足够的验证?软件越大、越复杂,内部的关联关系就越复杂。写代码之前所要考虑的方面就会越多。所以,拿到需求之后,不是直接写代码来满足用户需求,而是分析和设计。
盲人摸象的道理,大家都是知道的。要开发的系统,对于我们来说就是一只大象,我们就那些盲人。如果我们只考虑到我们自己的需求和现有的需求,那么我们“摸出”的“象”会是什么样子呢?是用户要的吗?不满足用户需求的软件就是存在逻辑上的bug。但是,我们现在有方法学(呵呵,这点比那些盲人强多了),我们可以分别按照自己的理解构造一个“象”的模型出来,然后通过讨论,最后设计出一只最像“象”的模型出来。这样就可以使我们的软件和用户的实际需求最接近了。在以后的日子里,我们可以根据这个模型来绘制自己心中的那只大象了。这也正式软件需要架构、子系统、模型、类的设计理由。至于我们用来分析和设计的统一建模语言(UML),只是为了让大家都有共同的沟通工具。想想如果每个人都会自己构造的“象”用一种语言来描述,那么沟通中会有增加多少麻烦?统一建模语言给大家带来标准的沟通方式外,还具有很强的扩展性和表达能力。