2

我有一个定义一种方法的接口。该接口有多个以不同方式实现该接口的类。

例如:

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 的新类来完成吗?

编辑: [我想弄清楚Antiifcampaign的这些人在做什么]

谢谢你的时间...

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,例如SomeJobFactory, AnotherJobFactory...

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>>();

当您添加新的作业工厂时,您不必在此示例中修改一行代码。

如果您的代码更静态,您可以使用 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 回答