2013-07-12 25 views
1

我試圖找出我是否正在以正確的方式查看遏制/委派。在這個例子中,我有一個Car和一個Radio類型。我有一個函數,它接受一個字符串並更改Radio對象的IsOn屬性的值。我想知道哪種方法(或兩種方法)是否能夠解決此問題的充分方法。正確地將請求委託給內部對象

(請忽略呼入串入所述開啓方法的驗證,爲簡單起見)

public int Year { get; set; } 
     public string Model { get; set; } 
     protected Radio radio = new Radio(); 
     public Radio MyRadio 
     { 
      get { return radio; } 
      set { radio = value; } 
     } 

     public class Radio 
     { 
      public string ModelNumber { get; set; } 
      public bool IsOn { get; set; } 
      public void TurnOn(string turnOn) 
      { 
       if (turnOn == "yes") 
       { 
        if (IsOn) 
         Console.WriteLine("The radio is already on"); 
        else 
        { 
         IsOn = true; 
         Console.WriteLine("You turned on the radio"); 
        } 
       } 
       else 
       { 
        if (IsOn) 
        { 
         IsOn = false; 
         Console.WriteLine("You turned off the radio"); 
        } 
       } 

      } 

     } 

我在主要方法測試此,輸出是在評論的每行的旁邊

Car c = new Car(); 
    Console.WriteLine(c.MyRadio.IsOn); //false 
    c.MyRadio.TurnOn("yes"); //you turned on the radio 
    Console.WriteLine(c.MyRadio.IsOn);//true 
    c.MyRadio.TurnOn("yes"); //the radio is already on 
    c.MyRadio.TurnOn("no"); //you turned off the radio 
    Console.WriteLine(c.MyRadio.IsOn); //false 

我想到要幹這種添加了以下功能Car類

public void CarChangesState(string s) 
     { 
      MyRadio.TurnOn(s); 
     } 
的另一種方法

我用下面的代碼測試它和一切工作按預期

Car c2 = new Car(); 
      Console.WriteLine(c2.MyRadio.IsOn);//false 
      c2.CarChangesState("yes"); //you turned on the radio 
      Console.WriteLine(c2.MyRadio.IsOn);//true 
      c2.CarChangesState("yes");//the radio is already on 
      c2.CarChangesState("no");//you turned off the radio 
      Console.WriteLine(c2.MyRadio.IsOn); //false 

就是一個例子比其他的更好嗎?從我讀到的Pro C# and the .NET Framework我有一種感覺,就像第一次迭代不是真正的委派,但我想知道一種方法比另一種方法更少有什麼缺點。

+1

有點偏題:爲什麼你要傳遞一個字符串到ChangeState方法中?更可讀的選項是'bool'。最好的選擇可能是一個'Enum RadioState'。傳遞一個魔術串真的感覺像是「字符串型」反模式。 – dss539

+0

這是個好主意。 – wootscootinboogie

回答

1

你的第二種方法是委派。這第一種方法不是。

代表團表示您要求某個對象(例如Car)打開收音機。 Car不知道如何打開收音機,但他知道誰做的。所以他將消息傳遞給Radio

你的第一種方法,簡單地暴露無線電對象,不是委派,因爲Car從來沒有收到開啓無線電的請求,因此從不委託請求開啓無線電。

此外,許多純粹主義者會批評你的第一種方法,因爲它違反了Law of Demeter,但實際上,爲了方便/易讀,我偶爾會這樣做。 (也許我只是一個蹩腳的開發有關係嗎?)

+0

第一種方式似乎更具說明性,即易於閱讀和理解,但也許我需要更好的命名約定。 – wootscootinboogie

+1

@wootscootinboogie對於它的價值,我發現在許多情況下有一個'Car.Radio'字段是個人可以接受的。這是模糊的東西之一,你的直覺和設計經驗會讓你感覺哪個更好。有一套公式化的指導方針會很好,但有時我覺得這只是一個品味問題。 – dss539

+0

這是您第一次學習時更大的問題之一。每個人都有自己的風格,並且很難區分事實,以確定他們的意思是相同的。我總是試圖從可擴展性和最佳實踐的角度思考問題,並且通過解決只有企業應用程序面臨的問題纔不會違反YAGNI(您不需要它)。 – wootscootinboogie

0

你也許指的是這樣的:

class Car 
    { 
     // Car 'has-a' Radio. 
     protected Radio radio = new Radio(); 
     public Radio MyRadio 
     { 
      get { return radio; } 
      set { radio = value; } 
     } 
     public void TurnOnRadio(bool onOff) 
     { 
      // Delegate call to inner object. 
      MyRadio.TurnOn(onOff); 
     } 
    } 

    public class Radio 
    { 
     public string ModelNumber { get; set; } 
     public bool IsOn { get; set; } 

     public void TurnOn(bool turnOn) 
     { 
      if (turnOn) 
      { 
       if (IsOn) 
        Console.WriteLine("The radio is already on"); 
       else 
       { 
        IsOn = true; 
        Console.WriteLine("You turned on the radio"); 
       } 
      } 
      else 
      { 
       if (IsOn) 
       { 
        IsOn = false; 
        Console.WriteLine("You turned off the radio"); 
       } 
      } 

     } 

    } 

由於Radion是,一輛車?不是,那麼汽車有 - 你打電話直接打開或關閉收音機。

Car c = new Car(); 
c.TurnOnRadio(true);