2

1 つのメソッドを定義するインターフェイスがあります。このインターフェイスには、そのインターフェイスを異なる方法で実装する複数のクラスがあります。

例えば:

interface IJob {
  void DoSomething();
}

class SomeJob : IJob{
  public void DoSomething() {
    // Do something ...
  }
}

class AnotherJob : IJob {
  public void DoSomething() {
    // Do something ...
  }
}

...

私のファクトリクラスには、これらのIFステートメントがたくさんあります

if (some condition)
{
   IJob job = new SomeJob (); 
else
{
   IJob job = new AnotherJob (); 
}

新しい条件が発生するたびにファクトリ クラスを変更しないようにする方法はありますか。IJob を実装する新しいクラスを追加するだけでこれを行うことはできませんか?

編集: [私はAntiif キャンペーンの連中が何をしようとしているのかを理解しようとしています]

御時間ありがとうございます...

4

4 に答える 4

5

何らかの方法で条件と決定を結び付ける必要があります。

Dictionary<int, Action<IJob>> _methods = new ...

辞書に記入してください:

_methods.Add(0, () => {return new SomeJob();});
_methods.Add(1, () => {return new AnotherJob();});

次にそれを使用します:

public IJob FactoryMethod(int condition)
{
   if(_methods.ContainsKey(condition))
   {
      return _methods[int]();
   }
   return DefaultJob; //or null
}

アプリケーションの起動時に辞書に入力する必要があります。設定ファイルから、または他のコードを使用して。したがって、新しい状態になったときにファクトリを変更する必要はありません。あなたはこの変種が好きですか?

于 2012-09-26T11:40:27.233 に答える
2

どこで何を作成するかを決定する必要があり、それには常に何らかの条件文が含まれる可能性があります。

ただし、合理的な命名規則に従うように調整したり、属性などのリフレクション サポートを追加したりできる場合は、リフレクションを使用してファクトリ クラスを変更する必要性を減らすことができます。

.Net でこれを行う方法については、この記事を参照してください。

文字列からクラス名へのマップに基づいて決定を下すことも、アプリケーションの起動時に読み込まれるメソッドに対する別の適切な回答のように、リフレクションによって実行時にクラスを作成することもできます。何かがマップを提供する必要がありますが、決定の多くを構成に移すことができる場合があります。

于 2012-09-26T11:48:10.033 に答える
1

それはドメインのダイナミクスに依存します。条件を非常に頻繁に評価する必要がある場合は、の実装ごとにある種のファクトリを使用できます。IJobたとえばSomeJobFactoryAnotherJobFactory...

それぞれにMeetsCondition、条件が満たされた場合に true と評価され、新しいインスタンスを返すメソッドがあります。

public class SomeJobFactory : Factory<IJob>
{
   public bool MeetsCondition() { ... }

   public IJob CreateInstance() { return new SomeJob(); }
}

そしてあなたのコードで

foreach(var jobFactory in allJobFactories)
{
   if(jobFactory.MeetsCondition())
   {
      return jobFactory.CreateInstance();
   }
}

また、IoC を使用してすべてのジョブ ファクトリを取得します。

allJobFactories = IoC.ResolveAll<Factory<IJob>>();

新しいジョブ ファクトリを追加する場合、この例のコードを 1 行も変更する必要はありません。

コードがより静的である場合は、起動時にオブジェクトが作成される DI と IoC を使用できます。

于 2012-09-27T11:41:24.477 に答える
-1

私はあなたを好みませんが、いつでもジェネリックを使用できます:

public IJob GetJob<T>() where : IJob ,new()
{
    IJob job = new T(); 
    return job;

}
于 2012-09-26T11:40:53.137 に答える