OO难题在Ruby中有了新解

发表于:2008-02-18来源:作者:点击数: 标签:rubyRuby
单一职责原则(SRP)认为,一个类应该有且只有一个改变的原由。换个说法,一个类中的方法应该出于同样的一种原由而改变,它们不应被不同原由所驱使,而导致朝着不同的方向改变。 举个例子来说,考虑一下以下的 Java 类: class Employee { public Money calcu
单一职责原则(SRP)认为,一个类应该有且只有一个改变的原由。换个说法,一个类中的方法应该出于同样的一种原由而改变,它们不应被不同原由所驱使,而导致朝着不同的方向改变。

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

clearcase/" target="_blank" >cccccc>

  class Employee
  {
   public Money calculatePay() {...}
   public void save() {...}
   public String reportHours() {...}
  }

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

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

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

  employeeBusinessRules.rb

  class Employee  def calculatePay ... endend

  employeeDatabaseSave.rb

  class Employee  def save ... endend

  employeeHourlyReport.rb

  class Employee  def reportHours ... endend

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

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

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

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

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

原文转自:http://www.ltesting.net