2014-01-16 78 views
0

我認爲接口不僅是一組成員,而且也是強制實現保持接口文檔中指定限制的「合同」。例如:交叉接口合同

interface IDevice 
{ 
    bool IsActive { get; } 

    int Address { get; } 

    /// <summary> 
    /// Raised when (IsActive == false) 
    /// and device was activated 
    /// </summary> 
    event Action Activated; 

    /// <summary> 
    /// Raised when (IsActive == true) 
    /// and device was deactivated 
    /// </summary> 
    event Action Deactivated; 

    /// <summary> 
    /// Raised when (IsActive == false) 
    /// and Address was changed 
    /// </summary> 
    event Action<int> AddressChanged; 
} 

而且我有沒有興趣激活/停用過程,但想知道什麼時候Address會發生變化,因此,鉛通過ISP,我創建了一個新的接口用戶:

interface IAddressee 
{ 
    int Address { get; } 

    /// <summary> 
    /// Raised when Address was changed 
    /// </summary> 
    event Action<int> AddressChanged; 
} 

現在IDevice樣子:

interface IDevice : IAddressee 
{ 
    bool IsActive { get; } 

    /// <summary> 
    /// Raised when (IsActive == false) 
    /// and device was activated 
    /// </summary> 
    event Action Activated; 

    /// <summary> 
    /// Raised when (IsActive == true) 
    /// and device was deactivated 
    /// </summary> 
    event Action Deactivated; 
} 

正如你看到的,IDevice的合同已經鬆動一個條件:AddressChanged事件只能在設備未激活時纔會提升(IsActive == false)。

我不能在IAddressee接口中記錄它,因爲它不依賴於IDevice,並且可能存在非設備實現。

這種情況是否正常?你會怎樣強迫IDevice實現正確的行爲?

我的新合同的概念,所以請打消我的幻想和疑惑

+0

你只是問如何評論接口,所以有人知道他們是如何工作的?我問的原因是因爲除了有關IDevices的AddressChanged特殊條件的評論之外,您還沒有失去任何其他內容。在任何情況下都沒有任何事情可以「強制」實施按照您的要求行事。但是也許你可以在你的AddressChanged事件處理程序中有一個「Debug.Assert(!sender is IDevice || sender.IsActive)」。 – Aaron

+0

好吧,評論是告訴合同實現的唯一方法,所以是的,我在問如何評論它。但我也想知道我是否以正確的方式思考它。我想,改變所有處理程序是一個壞主意。 – astef

+0

我認爲答案是「我該如何評論這個?」真的很主觀。我想我會把評論貼近IDevice聲明,因爲「:IAddressee」是相關的部分。但是,你真的預計有實現IAddressee而不是IDevice的對象嗎?如果你不這樣做,我會認爲離開IDevice,因爲它是更好的,無論如何。您的IDevice偵聽器無需爲激活/禁用註冊處理程序。換句話說,除非你有實現IAddressee的非IDevice對象,否則我認爲你沒有通過分解AddressChanged獲得任何東西。 – Aaron

回答

1

在這種情況下,抽象的條件就行了。他們表達了一些可能取決於頂級課程中沒有的信息。該條件稍後以適合特定後代的方式實施。在您的例子

interface IAddressee 
{ 
    int Address { get; } 

    /// <summary> 
    /// Can Address be changed? 
    /// </summary> 
    bool IsAddessChangeable { get; }; 

    /// <summary> 
    /// Raised when (IsAddessChangeable == true) 
    /// and Address was changed 
    /// </summary> 
    event Action<int> AddressChanged; 
} 

在實現IDevice類,查詢IsAddessChangeable將返回IsActive == false,在其他類別 - 根據所需的語義值。

+0

起初,我認爲這違反了ISP,因爲「IAddressee」必須依賴於它不使用的成員:「IsAddessChangeable」。但隨後我將所有事件都改爲方法,一切都變得清晰。由於AddressChanged合同,「IAddressee」用戶確實依賴於「IsAddessChangeable」。我建議你用事例擴展你的答案,用事件替換方法(參見編輯) – astef

+0

@astef我回滾了你的編輯,因爲這是對接受答案中代碼的重大改變。我建議你先從作者那裏得到關於你的編輯的反饋,或者發表一個單獨的答案。 –