4

「インターフェイスへのプログラミング」と「new」キーワードの使用を避けるという考え方が気に入っています。

しかし、同じインターフェースを持っていてもセットアップが根本的に異なる 2 つのクラスがある場合はどうすればよいでしょうか。私の特定のコードについて詳しくは説明しませんが、メソッド「DoStuff」とのインターフェースがあります。2 つのクラスがこのインターフェイスを実装します。1つは非常に単純で、初期化を必要としません。もう 1 つの変数には、設定する必要がある 5 つの異なる変数があります。これらを組み合わせると、DoStuff が呼び出されたときにクラスが動作する文字通り何百万もの方法が可能になります。

では、いつこれらのクラスを「新しく」するのでしょうか? 工場を使用することについて考えましたが、セットアップが大きく異なるため、この場合には適していないと思います。(ところで: 実際には、インターフェイスを使用する約 10 の異なるクラスがあり、それぞれが複雑なパイプラインの一部を形成し、それぞれに異なる構成要件があります)。

4

5 に答える 5

6

インターフェイスへのプログラミングの概念を誤解している可能性があると思います。newオブジェクト指向言語でオブジェクトの新しいインスタンスを作成するには、常にキーワードを使用する必要があります。インターフェイスにプログラムするからといって、その要件がなくなるわけではありません。

インターフェイスへのプログラミングとは、すべての具体的なクラスの動作が、具体的なクラス自体ではなくインターフェイスで定義されることを意味します。したがって、変数の型を定義するときは、具象型ではなくインターフェイスとして定義します。

あなたの場合、DoStuff各クラスが実装する必要があるときに具象クラスに実装するだけです(単純に実行するか、他の10個の初期化されたオブジェクトとセットアップを使用して実行するかに関係なく)。たとえば、を実装するインターフェイスIInterfaceとクラスがあるとします。のインスタンスを次のように宣言できます。SomeClassIInterfaceSomeClass

IInterface myInstance = new SomeClass();

これにより、このインスタンスを他の関数に渡すことができ、それらの関数はそのインスタンスのクラスの実装の詳細について心配する必要がなくなります。

于 2009-05-10T20:34:10.067 に答える
2

さて、あなたには本当に3つの選択肢があります。new を使用するか、factory を使用するか、DI コンテナーを使用します。DI コンテナーでは、おそらく 5 つの変数を何らかの構成ファイルに含める必要があります。

しかし、正直に言うと、自分を窮地に追い込むことで、必要以上に人生を難しくしているように思えます。理想に沿ってコーディングするのではなく、目の前の問題を最も簡単に解決できる方法でコーディングします。ハックジョブを行うべきだと言っているわけではありませんが、実際には、新しいものを使用したくないと言っていると、必要以上に人生が難しくなっています...

于 2009-05-10T20:43:47.477 に答える
1

何を使用するかに関係なく、ある時点でクラスを使用するためにクラスのインスタンスを作成する必要がありますが、それを回避する方法はありません。

それを行う方法は、達成したいことと、それらのクラスのセマンティクスによって異なります。

あなたが言及したクラスをそれらのフィールドで受講してください。

それらのフィールドはどこかから読み取ることができますか? 例として、構成ファイル?その場合、おそらく必要なのは、そのような構成ファイルからそれらのフィールドを初期化するデフォルトのコンストラクターだけです。

ただし、これらのフィールドの内容を外部から渡す必要がある場合は、それを回避する方法はありません。

おそらく、IoC コンテナーと依存性注入を確認する必要がありますか?

于 2009-05-10T20:31:18.200 に答える
0

多くの構成パラメーターをクラスに渡す場合、責任が多すぎる可能性があります。単一の責任のみを持つ小さなクラスに分割することを検討する必要があります。

実装するクラスへの依存関係が作成されるため、 new キーワードを回避することは価値があります。より良い解決策は、依存性注入を使用することです。

例えば

public interface IDoStuff
{
    void DoStuff();
}

public class DoStuffService
{
    private IDoStuff doer;

    public DoStuffService()
    {
        //Class is now dependant on DoLotsOfStuff
        doer = new DoLotsOfStuff(1,true, "config string");
    }
}

public class DoStuffBetterService
{
    private IDoStuff doer;

    //inject dependancy - no longer dependant on DoLotsOfStuff
    public DoStuffBetterService(IDoStuff doer)
    {
        this.doer = doer;
    }
}

明らかに、どこかに渡される IDoStuff オブジェクトを作成する必要があります。Inversion of Control (IoC) コンテナーは、これを実装するのに役立つ優れたツールです。詳細を知りたい場合は、 Castle Windsor Containerのチュートリアルをご覧ください。(他にもたくさんの IoC コンテナーがありますが、たまたまこれを使用しているだけです。)

あなたの質問の例は非常に抽象的なものだったので、この回答が役に立てば幸いです.

于 2009-05-11T19:33:13.993 に答える
0

私があなたを正しく理解していれば、問題は異なる初期化にあります。同じインターフェースを持つ 2 つのクラスを提供する必要があります。1 つは何も必要とせず、もう 1 つはいくつかのパラメーターを必要とし、複雑な初期化を呼び出します。

InitializationParameter を取得するコンストラクターを使用する必要があります。両方のクラスがそれを取得する必要があります。そこから何も取得する必要のないシンプルなインターフェイスを備えたもの。もう一方はパラメータを必要とし、そこから取得します。

初期化が心配な場合は、ファクトリを使用できます。この init パラメータを提供するインターフェイスを要求するだけで、ファクトリは指定した値に従ってオブジェクトを作成、初期化し、返します。

不明な点がある場合は、お問い合わせください。

于 2009-08-20T15:58:41.167 に答える