`
ijavagos
  • 浏览: 1187364 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

OO难题在Ruby中有了新解 (原文最终修订于 2006-08-21 凌晨02:27:38)

阅读更多

单一职责原则(SRP)认为,一个类应该有且只有一个改变的原由。换个说法,一个类中的方法应该出于同样的一种原由而改变,它们不应被不同原由所驱使,而导致朝着不同的方向改变。

举个例子来说,考虑一下以下的Java类:

class Employee
{
public Money calculatePay() {...}
public void save() {...}
public String reportHours() {...}
}
这个类由于拥有三种改变的原由,所以违反了SRP。第一种,是跟支付薪水方式有关的商业规则;第二种,是数据库的结构;第三种,是报表的时间格式的字符串。我们不希望这样一个单一的类会被这三种完全不同原由所影响,不希望因为会计认为需要每天改变报表的时间格式,或是DBA每天都要改变数据库结构,也可能是管理人员每天要改变支付薪水的方式,而去改变Employee类。相反,我们希望把这些方法分离到不同类中,这样它们就既能彼此互不干扰,又可随意改变。

当然这好像又与OO的概念相违背,因为一个好的对象应该包含所有操纵它的方法。分解的做法的确有这种趋势,我们因为不希望商业规则与报表格式混杂起来,所以就需要将这些方法放入到不同的类中。

然而,在Ruby中,情况会有些不同。仔细想想下面三个文件:

employeeBusinessRules.rb

class Employee
  def calculatePay ... end
end


employeeDatabaseSave.rb

class Employee
  def save ... end
end


employeeHourlyReport.rb

class Employee
  def reportHours ... end
end

由于在Ruby中,类是在运行时被创建的(也就是说,上面的代码也可视作是一段程序执行片断),类可能是在程序执行的任意时间被展开,更多的方法和成员也可能是在此时被赋到类上。在主程序中我们也许会看到一些诸如:

require 'employeeBusinessRules.rb'
require 'employeeDatabaseSave.rb'
require 'employeeHourlyReport.rb'

因此,类会在余下的程序开始执行前被构造完成。可是没有一个源文件包含了所有这三个不同的方法。实际上,这三个源文件对彼此一无所知,而这就意味着,这三个文件之间并没有耦合。

毫无疑问,我们必须要关注这些成员。为了能访问这些成员(分散在多个源文件中),我们搞不好会使得这些源文件拙劣的耦合起来。可是,假如你有那么一点点地关注并抽象的话,就能使得这些源文件非常漂亮的解耦,进一步的,还可以把这些方法保留在同一个类中(因此也在同一对象中)!

所以,在Ruby中,不用违反SRP原则,就可以把不同的方法放置在同一个类中,并且属于同一个类。你只需简单的将这些有着不同原由的方法放置在不同的源文件中即可。真是鱼与熊掌得其兼啊!

(原文链接网址:http://www.butunclebob.com/ArticleS.UncleBob.SrpInRuby; Robert C. Martin的英文blog网址:http://www.butunclebob.com/ArticleS.UncleBob

译者注:Robert C. MartinObject Mentor公司总裁,面向对象设计、模式、UML、敏捷方法学和极限编程领域内的资深顾问。他不仅是Jolt获奖图书《敏捷软件开发:原则、模式与实践》(中文版)(《敏捷软件开发》(英文影印版))的作者,还是畅销书Designing Object-Oriented C++ Applications Using the Booch Method的作者。MartinPattern Languages of Program Design 3More C++ Gems的主编,并与James Newkirk合著了XP in Practice。他是国际程序员大会上著名的发言人,并在C++ Report杂志担任过4年的编辑。




  


  
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics