-1

これは一般的な設計上の問題です。コンポーネントを切り離したり、実装ではなくインターフェースに書き込んだりするためにインターフェースをよく使用します。

interface IMyInterface
{
    void DoSomething();
}

static class IMyInterfaceFactory
{
    public static IMyInterface GetInstance()
    {
        return new MyInterfaceInstance();
    }
}

class IMyInterfaceConsumer
{
    IMyInterface mInterface;

    public IMyInterfaceConsumer()
    {
        this.mInterface = IMyInterfaceFactory.GetInstance();
    }

    public void UseTheInterface()
    {
        this.mInterface.DoSomething();
    }
}

私の質問は、代わりに var キーワードを使用することです。真の C# インターフェイスを使用するのではなく、設計上の意味で「インターフェイス」を作成します。

static class IMyInterfaceFactory
{
    // of course, this doesnt need to be a single instance
    static MyInterfaceInstance mSingleInstance; 

    // no longer programming to the interface, just returning the instance
    public static MyInterfaceInstance GetInstance()
    {
        // null coalesce
        return mSingleInstance ?? (mSingleInstance = new MyInterfaceInstance());
    }
}

class IMyInterfaceConsumer
{
    public void UseTheInterface()
    {
        // shorthand way, could also omit var, too 
        var myInterface = IMyInterfaceFactory.GetInstance();
        myInterface.DoSomething();
    }
}

この方法では、ファクトリを 1 回変更するだけでよく、ファクトリが返すインスタンスが消費する必要のあるメソッドをサポートしている限り、それは機能します。ただし、利点は、生成オブジェクトと消費オブジェクトが明示的なインターフェイスについて知る必要さえなく、何も存在しないことです。また、2 つ以上のメソッドを持つインターフェイスをきれいにサポートすることもできます (肥大化したインターフェイス宣言を防ぎます)。

明らかな欠点の 1 つは、(上記のように) 単一のインスタンスがキャッシュされているか、何らかのメモ化手法が使用されていない限り、「インターフェイス」からメソッドを使用するたびに、ファクトリがクラスを再インスタンス化する必要がある可能性があることです。

このアプローチの長所/短所は? これは一般的な方法ですか?

4

2 に答える 2

5

varキーワードについて動的または緩いものは何もありません。コンパイル時に静的型推論をトリガーします。

コードの 2 番目の部分は、

public void UseTheInterface()
{
    // shorthand way, could also omit var, too 
    MyInterfaceInstance myInterface = IMyInterfaceFactory.GetInstance();
    myInterface.DoSomething();
}

ファクトリ関数はまだ強く型付けされています。実際、インターフェイスを削除することで、コンシューマー コードをより緊密に結合することができます。

于 2012-09-19T21:08:47.437 に答える
1

Var キーワードは依然として技術的に強く型付けされているため、コードはそれがどのクラス/インターフェイスであるかを認識しています。それをオブジェクトにダンプすることを計画している場合、コードの残りの部分には、そのファクトリから何が出てくるのか見当がつかないと言っています。ただし、そのオブジェクトをキャストしてその中の何かを利用することになるため、お勧めしません。

「肥大化したインターフェイス宣言を防ぐ」ことでどこに行こうとしているのかわかりませんが、基本クラスまたは抽象クラスを拡張することでポリモーフィズムを行うこともできます。これにより、子クラス間で共通のコードはそのままにして、各子クラスの特定のコード (メソッドまたはプロパティ) をオーバーライドできます。

インターフェースをまとめて変更する場合は、インターフェースにインターフェースを実装する必要があります。この投稿 を参照してください。したがって、基本的にインターフェイス A にはメソッド DoStuff() のみがあり、このインターフェイスから継承する他のインターフェイスは、説明しているようにポリモーフィックに使用できます。

interface A
{

DoStuff();
}

interface B : A
{
DoSomethingElse();
}

class C : B
{

DoStuff(){}
DoSomethingElse(){}
}

ところで、上記の「シングル インスタンス キャッシュ」コードは、 シングルトンパターンと呼ばれるものに近いものです。

于 2012-09-19T21:17:27.507 に答える