【发布时间】:2016-07-05 11:48:40
【问题描述】:
我有一个(不断增长的)数据生成器列表。我需要的生成器是由工厂类创建的。生成器都实现了一个通用接口,其中包括一个静态字符串name。
我想做的事:使用上述名称的字符串参数调用 factory.Create 方法。 create 方法找到具有此名称的生成器并返回该生成器的新实例。
我认为这样做的好处是:我只需要添加新的生成器类,而不必编辑工厂。
问题:
- 这是处理此问题的好方法吗?
- 如何找到所有生成器?对接口的每个实现/命名空间的每个成员的反射(对于生成器 + 它们的接口是唯一的)?
- 将这种工作方式称为工厂是否正确,或者这是某种不同的模式?
最后我会这样称呼工厂(简化):
//Caller
public DataModel GetData2()
{
var generator = new DataFactory().Create("Gen.2");
return generator.GetData();
}
//Factory
public class DataFactory
{
public AbstractDataGenerator Create(string type)
{
//Here the magic happens to find all implementations of IDataGenerator
var allGenerators = GetImplementations();
var generator = allGenerators.FirstOrDefault(f => f.name == type);
if (generator != null)
return (AbstractDataGenerator)Activator.CreateInstance(generator);
else
return null;
}
}
//Interface
public abstract class AbstractDataGenerator
{
public static string name;
public abstract DataModel GetData();
}
//Data-Generators
public class DataGen1 : AbstractDataGenerator
{
public static string name = "Gen.1";
public DataModel GetData()
{
return new DataModel("1");
}
}
public class DataGen2 : AbstractDataGenerator
{
public static string name = "Gen.2";
public DataModel GetData()
{
return new DataModel("2");
}
}
工厂中的魔法GetImplementations() 应该通过反射完成还是以其他方式完成?我应该使用完全不同的方法吗?
因为答案是指 IoC 和 DI:这个项目已经使用了 NInject,所以它是可用的。 从接口切换到抽象类。
【问题讨论】:
-
我发现这种方法的一个问题是,为了获得生成器的“名称”属性,您需要一个对象实例。
-
这就是我将属性设为静态的原因。如果我没记错的话,这应该不需要实例。
-
接口不能有静态成员..
-
@stuartd 好评。我可以使用抽象类而不是接口。 - 编辑:完成。
-
@MilConDoin 在您的
abstract类上使用类似static的字段/属性会导致每次设置它时都会被覆盖。您可能需要重新考虑使用static字段
标签: c# design-patterns factory