web-dev-qa-db-ja.com

C#には、ISPを適用するときに、マルチインターフェイスで宣言されたインスタンス、または同様のものを使用する方法がありますか?

ISPについての私の理解は、定義(下記参照)の「クライアント」は、インターフェイスを実装するクラス、またはウィキペディアの定義で言及されているクライアントに基づいて、さまざまなインターフェイスオプションの1つで宣言されたインスタンスのいずれかを意味します。

インターフェース分離の原則(ISP)では、clientは、使用しないメソッドに依存することを強制されるべきではないと述べています。 [ソース]

インスタンスが使用されている場合 であるとするSEの投稿や、 インターフェースが実装されている場合 であるとするSE投稿を見てきました。 このSEの回答 によると、両方と考えることができます。だから私はそれがどちらかである可能性があることを念頭に置いて問題に続きます。

私が構築している特定のアーキテクチャでは、すべてのインターフェイスを実装する1つのクラスがありますが、インスタンスを使用するときにインスタンスを柔軟に表示したいとします。

public interface IAutoToggle
{
    IEnumerable<IToggleable> Toggle(IAttribute attribute);
}

public interface IManualToggle
{
    void Toggle(IEnumerable<IToggleable> toggles);
}

public interface IMixedToggle: IAutoToggle, IManualToggle {}

public class Toggler : IMixedToggle
{
    //...implementations
}

これで、インスタンス化されるときに、2つのうちの1つまたは両方を実行するかどうかを決定できます。

IMixedToggler mixedToggler = new Toggler();
//or
IAutoToggler autoToggler = new Toggler();
//or
IManual manualToggler = new Toggler();

このやり方は、依然としてインターフェース分離の原則に従っていますか?

もしそうなら、追加の継承されたインターフェースなしでC#で同じ効果を行う方法はありますか?たとえば、Objective-Cは、より動的な言語であるため、私が間違っていなければ、次のようなことができます。

id<IAutoToggle, IManualToggle> toggler = [[Toggler alloc] init];

C#で余分なIMixedToggleインターフェイスを回避する方法はありますか(上記のObjective-Cで行ったように)?それとも、私がやっている道をたどらない理由はありますか?

3
morbidhawk

インターフェイス分離の原則(ISP)は、クライアントが使用しないメソッドに依存することを強制されるべきではないと述べています。

上記の定義はそれを意味すると思います

クライアントを強制するべきではありませんメソッドを実装するため使用しません

インターフェイスのコンシューマーが複数のメソッドを持つインターフェイスに依存することは問題ありませんが、そのうちの1つだけを使用します。

したがって、あなたの場合、導入できるインターフェースは1つだけです。

public interface IToggler
{
    IEnumerable<IToggleable> ToggleByAttribute(IAttribute attribute);

    void Toggle(IEnumerable<IToggleable> toggles);
}

そして実装

public interface Toggler : IToggler
{
    IEnumerable<IToggleable> ToggleByAttribute(IAttribute attribute) 
    { 
        // Implementation
    }

    void Toggle(IEnumerable<IToggleable> toggles)
    { 
        // Implementation
    }
}

いずれかのメソッドに複数の実装がある場合にのみ、インターフェイス分離の原則の適用を検討できます。

0
Fabio