架构设计最佳实践之Don’t Repeat Yourself

日期: 2009-11-25 作者:陈序明 来源:TechTarget中国 英文

  大多数的开发人员在讲DRY(Don’t Repeat Yourself)的时候大多认为DRY是功能和代码的重复,也就是OAOO(Once And Only Once),其实不尽然。面向对象设计提倡的OAOO,强调的是利用面向对象的继承、组合等特性尽量让一个功能点只存在一个地方,所以OAOO强调的是面向对象设计,以及功能代码方面。而DYR的范围比OAOO要广泛得多。DYR更多的是一种架构设计思想,在软件开发过程中的万事万物均可能重复,大到标准、框架、开发流程;中到组件、接口;小到功能、代码均纯存在自我重复。而DYR提倡的就是在软件开发过程中应消除所有这些自我重复。

    在软件过程中的自我重复,总的来说有五种类型:

  (1)一件事物,有多种的不同语言和方式来表达,不同的角色采用不同的语言去描述同一事物。在这些角色之间需要协同工作时造成的重复。

  比如,架构设计师用一种语言和方式描述其架构设计,可为PPT、Word文档、Visio、建模工具等。开发人员的工作语言则是程序代码。两种角色描述的是同一事物,只是描述语言不同而已,这样造成架构设计师的架构输出,不能作为开发人员的开发输入,而不能被开发人员重用,导致一定的自我重复。这就像一个人用英文写书,一个人用中文写书,内容类似,那么中文作者要么重新整理内容并书写书籍,要么就翻译英文书籍,不管哪种,造成重复工作劳动是在所难免。

  对于此类的自我重复,随着模型驱动的成熟和广泛应用将逐渐减少。模型驱动架构中业务建模、架构建模和程序编码等之间,通过Unified Modeling Language(UML)、the Meta-Object Facility (MOF)、XML Metadata Interchange(XMI)和自动化代码生成等语言、标准和技术进行互相转换,达到Don’t Repeat Yourself。如下图所示:

传统开发过程和MDA开发过程

  传统的开发过程中,需求、分析、设计、开发等各个阶段,可能采用不同的描述语言和方式,互相之间也较难转换,所以他们之间不能无缝的相互转换,造成了重复沟通、理解和建模。

  模型驱动开发,在开发过程的每个阶段基于标准和转换工具,所以每一个阶段的成果,都可以被下一个阶段复用,消除重复。这也是标准的魅力之一吧。

  (2)同一件事物,不同的人各描述了该事物的不垃圾广告面,造成他们之间所描述的事物既类似又不同,有重复的地方,又不完全一样,导致自我重复。

  比如,银行中的用户信息模块,在“网上银行”、“公积金贷款”,和“信用卡系统”中各自都可能有一个模块,从数据库、到逻辑、到界面都各自重复一套,他们之间既类似又有一些区别,如需要的信息不一样。导致这些模块之间的自我重复。

  对于此类的自我重复,是由架构设计导致,在架构设计阶段没有按照“组件化”、“服务化”和“层次化”的架构设计,造成在一个事物不能符合不同模块和系统的需求,并且无法扩展。

  这种自我重复,在企业的遗留系统和新系统之间尤为明显。因为大多企业的老系统在构建时由于技术、组织结构等原因,都是采用垂直的渠道架构,即存储层、逻辑层、展现层完全重新实现,甚至连技术框架都和其他渠道相异。如某银行业的多渠道应用中,不同渠道(如网上银行和手机银行)的逻辑类似,但在两个系统中重用性不高,存在着大量的自我重复。如下图左所示:

大量的多渠道架构和可重用的多渠道整合架构

  随着SOA(Service Oriented Architecture)的广泛使用,再辅助以层次化架构,能有效解决此类问题。

  重复的组件要被重用,就需要是组件化的,并且能够被访问到。EJB、Web Service以及相应的组件化、基于服务的设计思想,一定程度解决了这些问题,缓和了在企业架构中的重用性问题。

  而层次化的架构设计则既是解决架构重复的途径,也是结果。层次化的架构演变过程,可以在人类社会发展过程中找到似曾相似的影子。在人类社会中,任何事情重复到一定程度,就会产生一个新的职业或阶层,比如,找房子的人多了,就自然会产生中介。在架构设计中也是一样。任何设计重复到一定程度,就应该抽象出新的层次。这个层次也许可以作为一个新的组件,也可能做出一个新的产品。

  上图2右边的架构,是银行多渠道整合的架构设计,是基于SOA架构的、多层次高度重用的架构设计,银行在新增一个渠道(如增加ATM渠道)时,能够重用大量的其他渠道的组件。

  (3)没有自我重复,但重复别人。指一个功能有很好的免费开源框架或者标准可以依据,但设计开发时没有采用,而重新发明轮子,导致不能重用已有的标准或开源框架的优势。

  记得几年前参加的一个企业信息管理系统的产品开发,该产品从底层MVC框架开始开发,还开发了界面UI控件、自己的XML流程引擎实现等,然后才是在这个基础上开发该企业的信息管理系统。最后结果如何可想而知:投入产出比失衡,以失败告终。这是一个典型的“没有重复自己,但重复标准或免费成熟框架”的例子。

  在商业中的专业分工、竞争优势理论和软件架构思想有很多相通之处。一个开饭店的,不应该去种大米、白菜或养猪,而应该抓住自己的核心竞争优势,开好饭店。相同的,种菜的、养猪的,也不应该无缘无故跑去开饭店。除非他们各自都想转行,进入另外的专业化分工领域,同另外领域内公司竞争。

  在软件业中也是一样的道理,每个产品都有其核心竞争力,每个产品都应该把握住本产品的核心竞争力,并投入最大的人力物力去经营。而对于其它的标准、辅助工具、框架或产品等,应该持开放的态度,复用已有的标准、成熟框架或产品。当然,除非你想重新定位你的产品。

  这种类型的错误技术人员经常会犯,但作为产品的架构设计师,应该尽量杜绝这种错误的发生。

  (4)开发过程中信息重复,如软件过程中用到的工具(项目管理系统、开发工具、测试计划及用例、Build工具、版本管理工具等)之间的信息重复;还有软件过程中各种角色的沟通重复,如开发人员报告进度给开发组长、开发组长又重新报告进度给项目经理等。如下图所示:

软件过程中的信息重复和沟通重要

  对这一类型的自我重复,一个集成的协作平台能解决问题。基于这个协作平台,软件过程中所有角色、工具和流程都能无缝的协作,消除了信息重复和沟通重复,加快开发效率。如下图所示:所有的工具无缝集成,消除了信息重复;所有的角色都基于一个协作平台,能够实施反映产品的状态、信息、各种历史记录等,极大降低了沟通重复。

集成协作平台

    (5)缺乏重构导致自我重复。这一种自我重复是最幼稚且低级的重复,但在很多产品的代码和文档也大量存在。一个功能在不同模块中重复拷贝使用、对象继承和组合关系混乱、文档关系混乱等都属于这一类的问题。

  对于这一类型的自我重复,对软件进行持续重构是唯一的好方法。代码重构具体请参考《重构》这本书;至于文档重复,大家不妨把《重构》的思想应用于文档,也必有所得。

  总结

    Don’t Repeat Yourself,是软件开发的最佳实践,良好的软件开发应该是非自我重复的,同样按照非自我重复思想设计开发的软件,往往是好的软件。

  · DRY,消除软件开发的各个阶段之间的重复,以客户和需求为中心,加快开发速度。
  · DRY,遵循”组件化”、”服务化”、”层次化”的架构设计,使得架构清晰,层次分明,并易于重用。
  · DRY,不自我重复,也不重复别人,特别是标准和成熟的开源框架,使得架构开放,稳定,并减少成本。
  · DRY,不重复信息,不重复沟通,改进管理流程,加快开发速度,达到有效沟通。
  · DRY,持续重构代码,文档等,保持软件简介、清晰,便于维护。

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

相关推荐

  • 企业数据移动化

    企业正努力通过RESTful接口实现企业数据的移动化,但开发移动应用和REST API是非常耗时的工作。我们研究了两种技术,可以显著缩短上市时间。

  • 敏捷开发的二十六条至理名言

    敏捷开发真正的问题是什么?其实敏捷主要还是一种观念,一种意识,通过人来推动。我经常收集各种各样的至理名言,最近我重温敏捷开发,下面是……

  • 模型驱动开发的误解和挑战

    如果你过去尝试过MDD,那你很可能遇到了一些挫折,导致你现在不再用它。也或许你正在尝试采用MDD,而又面临着一些挑战和阻碍。无论你遇到上述哪种情况……

  • 敏捷开发中的架构设计初探

    敏捷开发是一种软件过程方法和工具,敏捷开发本身并不能代表架构设计。这就好比建筑架构设计和建筑工程管理之间的差别一样,两者是建筑的两个……