【IT168 技术文章】
DRY——Don't Repeat Yourself Principle,直译为“不要重复自己”原则。
DRY简而言之,就是不要写重复的代码。原则本身很简单,但是,对于OOAD来说,有着非常重大的意义。
DRY利用的方法就是抽象:把共同的事物抽象出来,把代码抽取到一个地方去。这样就可以避免写重复的代码。
举一个DRY的典型例子,如果在一个类构造的时候,需要进行成员的初始化,在进行了某些操作以后,同样要进行初始化,那么就可以把“初始化”抽象出来,做成一个方法Initial(),在构造和需要用到的地方调用它。
虽然,抽取重复代码是利用DRY的一个好的开端,但DRY的实质是,一个需求,用一个部分来完成。当你试图避免重复代码的时候,实际上,你做的应该是用一段代码来完成一个需求。
为什么要用DRY原则?DRY会给代码维护带来很大的好处。以类的初始化为例,假设类修改了,增加、减少或是修改了成员,如果不写 Initial(),那么你可能至少要修改两处,而且,修改之处也可能出现不一致,维护成本大大增加。而写了Initial()方法,那么只要集中修改 Initial()就行了。
既然DRY是关于“一个方法,实现一个需求”的,那么,是不是可以把DRY应用到需求分析中?呵呵,答案是肯定的,而且,个人认为,这是个非常好的主意。多个重复的需求可能导致多个重复或者相近的类,最后导致重复代码。所以DRY绝不仅仅对代码适用,它是一个广泛适用的原则。
接下来举例说明DRY原则如何提升软件质量,结合作者的实践,以某网上营业厅3期项目为例,讨论了DRY原则在整个软件生命周期过程中,对于保证软件质量的指导作用和意义。
这其中包括了需求分析阶段,软件设计和开发以及软件测试等阶段。通过在这些软件过程中使用DRY原则,提高了软件的易用性,可维护性和可扩展性等重要的软件质量评价指标。最后,作者提出了对DRY原则的展望和未来围绕DRY原则可能出现的新工具、新方法。
先介绍一下项目吧,2008年8月到2008年12月,我参加了某省级无线运营商的网上营业厅3期项目,在这个项目中,我担任了项目经理的角色。
网上营业厅是该运营商的省级网上门户,是电子化营销渠道的重要组成部分。其主要功能包括:企业形象宣传;新业务、新活动推广;客户进行业务查询和办理等。随着客户对电子渠道认知度的提升,原有的网上营业厅2期在硬件方面,已经无法满足日益增长的客户数。在软件架构方面,已经无法快速响应频繁复杂的需求变更。因此,该运营商提出了对于网上营业厅3期项目的建设计划。3期建设的预期目标为:把网上营业厅的注册客户数从200万提升到500万,并从硬件、软件等各方面保证客户正常使用。
该项目的人员组成包括:1名项目经理,1名软件开发经理,1名系统实施经理,3名程序员,2名页面制作,2名系统实施共10人。项目的开发平台为J2EE。
该项目的硬件大体情况为:14台IBM BCH ,安装apache,作为 web前端服务器。6台IBM P52A,安装weblogic,作为应用服务器。2台IBM P570作为身份认证服务器。2台IBM P570,安装oracle,作为数据库服务器。操作系统使用了红帽企业版 linux 5,以及AIX5.3。
目前,网上营业厅3期成功通过终验,并按时上线。在月初、月末的业务办理高峰期,能够保证客户的正常访问。此项目得到了该省级无线运营商和我所在公司领导的认可。
首次接触“DRY原则”这个概念时,我认为它仅仅是应用在编码范畴的一个编码原则,旨在帮助程序员避免使用复制,粘贴等手段,到处拷贝代码。随着对软件项目的认识和实践,我发现DRY原则实际上是贯穿整个软件生命周期的,保证软件质量的重要原则。从广义上来讲,软件中的各种资源和代码一样,都可能面临着被到处复制的危险。当客观条件发生变化,要求资源发生变更的时候,就要同时修改多个资源。如果这些资源被重复地使用在系统中的各处,将直接影响软件质量中的可维护性和可扩展性因素。
下面,我将结合网上营业厅3期项目,详细论述我们的项目组是如何在项目中成功地借助DRY原则来保证软件质量的。在需求分析阶段,我们曾经遇到这样一个问题。客户使用系统前,首先用手机号码和密码登录。当客户办理某个业务的时候,系统会向客户发送短信验证码,客户需要将该验证码输入到网页中的验证框中,验证通过后才能办理业务。系统通过短信二次验证码验证了客户确实是该号码的拥有者。这种验证本来是合理且有效的,但在2期系统中,当客户办理完一个业务想再办理另外一个业务的时候,还要再次进行短信二次验证。也就是说,每办理一个业务,就要进行一次短信验证,客户体验可想而知。经验告诉我,这个需求违反了DRY原则。我们通过和2期的设计人员以及客服人员进行沟通,发现2期系统这样设计的初衷是为了提高安全性。其实,仔细分析就会知道,这种验证方法保护的是客户在登录期间丢失手机的账户安全。简言之,2期系统的验证方法牺牲了绝大多数客户的使用体验,却仅仅保护了极小概率发生的特殊情况。不仅给客户重复地发短信验证码,影响了客户体验,而且提升了系统的开销。最后,在DRY原则的指导下,我们把短信验证改为了一次登录期间仅验证一次,极大地提升了客户体验,进而从易用性方面提升了软件质量。
在设计和开发阶段,DRY原则可以在更多的方面对软件开发进行指导。例如对于系统运行期异常处理机制的设计。每一个业务处理过程都可能发生异常,所以需要专门的异常处理代码来处理异常情况。网上营业厅目前拥有约40多项业务,虽然各个业务的正常处理流程各不相同,但发生异常后的处理流程却是完全相同的。我们在做系统流程设计时,根据DRY原则,充分考虑了这种情况。最后决定,使用过滤器来统一各个业务的异常处理流程,将分散在系统中的异常处理模块设置到过滤器中。当异常处理流程变更时,我们仅需要在过滤器这一处对其进行修改,大大降低了软件的维护成本。
再一个例子是数据库访问通用模板类设计。网上营业厅是免不了对数据库进行操作的。大家知道,从数据库获取连接,使用连接,并在最后关闭连接,是每次使用数据库必须做的操作。如果我们在所有模块中的数据库访问都执行这3步操作,那将会浪费巨大的人力成本。在DRY原则的指导下,我们提炼了数据库操作的一个流程模板,那就是获取连接,使用连接和关闭连接。通过结合面向对象的设计方法,我们设计了一套对数据库进行操作的模板类。使用这套模板类,开发人员只需把精力集中到对数据库连接的使用上,也就是更加专注于业务逻辑。而无需关心连接的获取,关闭等操作。这样做不但节约了时间,也节省了人力,而且提高了软件的可维护性和可扩展性。
在软件测试方面,DRY原则仍然具有用武之地的。例如测试用例的设计。不论是白盒测试还是黑盒测试,DRY原则已经潜移默化地融入了这些测试用例的设计原则当中。例如白盒测试就是要尽量避免重复的路径覆盖;而黑盒测试中的等价类划分技术,也是要避免重复的测试数据被使用。从而提高了测试的效率,加快了软件故障或新需求的处理速度,提高了软件的可维护性。
通过以上论述可知,DRY原则是一项可以贯穿整个软件生命周期的指导原则。通过项目组正确地应用和实践这一原则,我们从最大程度上保证了网上营业厅3期的易用性,可维护性,可扩展性等重要的质量指标。 DRY原则的应用领域还不止这些,它的某些观点在目前看来似乎过于超前。例如DRY原则认为:软件的设计文档是对代码的重复,软件的需求文档是对验收测试文档的重复,软件模型是对数据库结构的重复等等。我认为,随着软件开发技术和工具的进步,在不久的将来,也许软件的设计文档完全可以通过代码自动生成,软件的需求文档也能够自动转化为验收文档等等。围绕DRY原则,也一定会涌现出一大批优秀的软件工程工具。这样一来,我们就能够进一步发挥DRY原则的作用,最大限度地对各个实体进行解耦,让系统中的每一项功能仅由一个实体来完成。DRY原则一定会对软件质量的保证有着越来越重要的作用和意义。