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.anti-gravitydesign.com

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97