2009-03-02 74 views
0

我的問題的總結是「我有2個共享一個通用接口的類,但是這兩個類在屬性方面有不同的行爲。一個接口拋出一個異常,如果參數值無效,另一個接口將其內部狀態更新爲處理無效的值,兩個類是否可以共享相同的接口,或者應該定義兩個接口,以向開發人員指出兩者具有不同的行爲?「可以使用相同的接口定義但提供不同的行爲嗎?

我會嘗試用一些代碼來澄清。我有界面定義如下。

 
public interface IStationDictionary 
{ 
    bool this[string stationId] { get; set; } 
} 

和一個實現接口的類,該類用於設置數字IO板上的輸出端口。

 
public class DigitalStationAdapter : IStationDictionary 
{ 
    public bool this[string stationId] 
    { 
     get { return ports[stationId].Value; } 
     set { ports[stationId].Value = value; } 
    } 

    public void AddDigitalStation(string stationId, DigitalIoPort port) 
    { 
     ports.Add(stationId, port); 
    } 

    private IDictionary<string, DigitalIoPort> ports = new Dictionary<string, DigitalIoPort>(); 
} 

我也有記錄哪些站有改變,因此這些改變可以propegated到數字IO值的類。

 
public class StationTransitions : IStationDictionary 
{ 
    public bool this[string stationId] 
    { 
     get 
     { 
      bool result = false; 

      if(changes.ContainsKey(stationId)) 
       result = changes[stationId]; 

      return result; 
     } 
     set 
     { 
      if(!changes.ContainsKey(stationId)) 
       changes.Add(stationId, value); 
      else 
       changes[stationId] = value; 
     } 
    } 

    public IDictionary GetChanges() 
    { 
     IDictionary<string, bool> result = changes; 

     changes = new Dictionary<string, bool> 

     return result; 
    } 

    private IDictionary<string, bool> changes = new Dictionary<string, bool>(); 
} 

所以,雖然這兩個類實現相同的接口,如果你試圖用的stationID訪問索引不在字典DigitalStationAdapter將拋出一個KeyNotFoundException。而StationTransitions將會成功,即不同的行爲。這沒關係,我認爲接口用於定義行爲和結構?基思。

回答

2

這很好。這樣考慮:確定任何繼承關係是否「OK」的關鍵是Liskov substitution principle.這要求期望基類的代碼應該能夠在不知道它的情況下使用派生類。這意味着一個方法的先決條件不能在派生類中加強,但可以被削弱。接口只是基類的特例。

在你的情況下,接口的隱式前提條件是輸入在你定義時是有效的。所有期望基類的代碼應該假設這個前提條件,並避免傳遞無效數據或準備處理異常。在更新其內部狀態來處理無效輸入的具體類中,你正在弱化一個先決條件。就Liskov替代原則而言,這是可以接受的。另一方面,如果你想讓自動處理無效輸入的類拋出一個基類,並使拋出後裔的類失效,這將會很糟糕,因爲代碼期望基類類不能像派生類一樣使用派生類。它必須知道派生類才能處理可能的異常。

相關問題