2016-06-17 83 views
0

創建接口這是第一個想到的,而讀Interface Implementation (Interface Segregation Principle)接口實現 - 中參數

思想

介紹那會表示方法的參數而不是傳遞各個參數值​​,新的界面我得到了。如下圖所示:

interface IServiceProviderInput 
{ 
    string Username { get; } 
    string Password { get; } 
    string AgentId { get; } // XYZServiceProvider needs this. 
    // Similarly add props here to represent new parameters 
    // required by future service provider implementations. 
} 

interface IServiceProvider 
{ 
    bool Authenticate(IServiceProviderInput parameters); 
} 

class ABCServiceProvider : IServiceProvider 
{ 
    public bool Authenticate(IServiceProviderInput parameters) 
    { 
     return true; 
    } 
} 

class EFGServiceProvider : IServiceProvider 
{ 
    public bool Authenticate(IServiceProviderInput parameters) 
    { 
     return true; 
    } 
} 

class XYZServiceProvider : IServiceProvider 
{ 
    public bool Authenticate(IServiceProviderInput parameters) 
    { 
     return true; 
    } 
} 

問題

請問這是否有意義,或者什麼都在這個破綻?有什麼想法嗎?

編輯

又一想增加更多的特定接口的XYZ提供商:

interface IServiceProviderInput 
{ 
    string Username { get; } 
    string Password { get; } 
} 

interface IXYZServiceProviderInput : IServiceProviderInput 
{ 
    string AgentId { get; } 
} 

class XYZServiceProvider : IServiceProvider 
{ 
    public bool Authenticate(IXYZServiceProviderInput parameters) 
    { 
     return true; 
    } 
} 

這可能是兩種想法是不正確的或有缺陷,我不知道,因此問題。

+0

爲什麼輸入屬性有setter?這對我來說很奇怪。您希望服務提供商能夠更改輸入的屬性值嗎? – recursive

+0

@recursive服務不會設置它們。調用代碼如何設置參數值呢? – niksofteng

+1

調用代碼不需要通過此接口專門訪問它們。界面的目的是通過責任將相關操作分組在一起。如果這個責任是作爲一種輸入,那麼接口上就不需要一個setter。但這並不意味着setter不能存在於實現或更多派生的接口上。 要使用另一個示例,即使您可以在「List 」上,也不能'將一個項目添加到'IEnumerable '。 – recursive

回答

2

你當然可以做到這一點,但除非所有的方法接受和需要所有參數定義的參數是一個可怕的想法。不要將更多的信息傳遞給一個方法,否則你不知道什麼是工作所需要的,什麼不是來自界面。

+0

因此,爲了僅提供需要的參數,我提到了思想#2,其中創建了'IXYZServiceProviderInput',但是對於多種方法來說,這樣做會更糟或不切實際。那麼我們是否認爲這實際上是個壞主意,應該嚴格避免?或等待更多人的想法? – niksofteng

+0

您可能最終會爲每個方法參數提供接口。我敢肯定有人會爭辯說「做出偉大的單元測試」,但沒有具體的理由要做,我不會推薦它。現在,如果我們真的關注OOP,並說所有這些函數都需要一個IPerson並從概念上對IPerson數據起作用,那麼它就更加可以接受,但即使如此,您也希望避免在方法可能意外失敗的狀態下構建一個Person對象的路徑,因爲用戶忘記設置一些領域,沒有明顯的方法讓他們知道是必需的。 –

0

我唯一的問題與你的實現是爲什麼你使用XYZServiceProvider相同的身份驗證方法,但沒有實現您定義的接口IServiceProvider

問題是,當您有客戶端正在呼叫IServiceProvder進行身份驗證時,他們將無法使用XYZServiceProvider,但只能使用其他兩個。如果他們想要使用XYZServiceProvider,他們需要按名稱(緊密耦合)來指定它。

如果你要更改您的程序,然後從XYZServiceProvider切換到EFGServiceProvider用,那麼個人用戶還需要改變他們的代碼,使他們能夠使用新的供應商進行認證。當試圖爲您的服務創建單元測試時,這是特別麻煩的,因爲您將不得不單獨創建XYZServiceProvider的測試裝置。

如果您打算爲XYZServiceProvider提供備用服務類型,我建議您創建另一個接口,如用於其他服務的IServiceProvider

+0

啊,你在我發佈我的答案之前就改變了它。這是更好 – ghg565

+0

我改變了它發佈你的答案,否則我不會重新思考我錯過了。你認爲以前的代碼版本是有效的。感謝您指出了這一點。你現在對於更新和最終的代碼有什麼想法? – niksofteng

+0

我仍然認爲XYZServiceProvider應該實現IServiceProvider接口。該參數仍然是IServiceParameterInput類型,因此這將允許您對「IServiceProvider.Authenticate(IServiceProviderInput參數)」進行身份驗證,然後將具體內容保留在實現中。 – ghg565