2016-06-17 15 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

なぜ入力プロパティにセッターがあるのですか?それは私には奇妙なにおいがする。サービスプロバイダが入力のプロパティ値を変更できるようになると思いますか? – recursive

+0

@再帰的サービスはそれらを設定しません。それ以外の場合、呼び出しコードはどのようにパラメータ値を設定しますか? – niksofteng

+1

呼び出しコードは、このインターフェイスを介してのみ呼び出すコードにアクセスする必要はありません。インターフェースの目的は、関連する操作を責任でグループ化することです。その責任が入力として機能するのであれば、インターフェース上にセッターは必要ありません。しかし、これは、実装者またはより派生したインタフェース上に存在することはできません。 'List 'であっても、別の例を使用するには、項目を 'IEnumerable 'に '.Add()'することはできません。 – recursive

答えて

2

あなたは確かにこれを行うことができますが、すべてのメソッドがインターフェイスによって定義されたすべてのパラメタを受け入れ、必要としない限り、それはひどい考えです。より多くの情報をメソッドに渡すことは決して必要ありません。そうでなければ、動作するために何が必要か、インターフェースからは得られないものを知る手がかりがありません。

+0

私は 'IXYZServiceProviderInput'を作成したと思ったが、必要なパラメータだけを提供することにしましたが、複数のメソッドに対してそうすることはさらに悪くて実用的ではありません。それは実際には悪い考えであり、厳密に避けるべきだと私たちは結論づけていますか?それとも他の人たちの考えを待つか? – niksofteng

+0

最終的には、すべてのメソッドのパラメータのためのインターフェイスを持っている可能性があります。私は、誰かが "素晴らしいユニットテストのために作る"と主張するだろうと確信していますが、特定の理由がなければ私はそれをお勧めしません。今、OOPに従っていれば、これらすべての関数がIPersonを受け取り、概念的にはIPersonのデータを扱うとすれば、それははるかに受け入れられますが、たとえメソッドが予期せず失敗する状態でPersonオブジェクトを構築するパスを避けたいとします。ユーザーはいくつかのフィールドを設定するのを忘れて、分かりにくい方法がないことがわかっていなければなりませんでした。 –

0

XYZServiceProviderで同じ認証方法を使用していて、定義したIServiceProviderインターフェイスを実装していないのはなぜですか?

この問題は、IServiceProvderを認証用に呼び出しているクライアントで、XYZServiceProviderを使用できなくなり、他の2つしか使用できない場合に発生します。 XYZServiceProviderを使用する場合は、名前で指定する必要があります(密結合)。

プログラムを変更してXYZServiceProviderからEFGServiceProviderに切り替えて認証する場合、個々のクライアントは新しいプロバイダを使用できるようにコードを変更する必要があります。 XYZServiceProviderのテストフィクスチャを個別に作成する必要があるため、これはサービスの単体テストを作成するときに特に問題になります。

XYZServiceProviderの代替サービスを利用する場合は、他のサービスに使用されるIServiceProviderのような別のインターフェイスを作成することをお勧めします。

+0

ああ、私は自分の答えを投稿する前にそれを変更しました。それはより良いです – ghg565

+0

私はあなたの答えを掲示してそれを変更した場合、私は逃したものを再スライスしていないでしょう。以前のコードバージョンでは有効だと思いました。それを指摘してくれてありがとう。あなたは今更新された最終コードについてどう思いますか? – niksofteng

+0

私はまだXYZServiceProviderがIServiceProviderインターフェイスを実装する必要があると思います。このパラメータは、IServiceParameterInput型のままです。これにより、 'IServiceProvider.Authenticate(IServiceProviderInput parameters)'を認証し、その実装を実装内に保持することができます。 – ghg565

関連する問題