我正在实施一个看起来如下的工厂模式。
public class FeedFactory
{
#region Singleton Pattern
//..
#endregion
private static Feed[] _factory = new Feed[(int)FeedType.Total];
public void RegisterFeed(FeedType feedType,Feed feed)
{
if (_factory[(int)feedType] == null)
{
_factory[(int)feedType] = feed;
}
else
{
// already registered
}
}
public Feed GetFeed(FeedType feedType)
{
return _factory[(int)feedType];
}
}
这里,Feed
是一个抽象类,不同的类从中继承。如何注册不同的课程?是否可以从构造函数中完成它?
答案 0 :(得分:7)
这不是工厂模式。工厂总是会有一些构造函数逻辑,至少有一个new
。这就是工厂的想法:调用者不必担心如何创建对象。这是一个单例存储库。
首先,不应该使用数组,而应该使用类型索引字典。
private static Dictionary<Type, Feed> _singletons = new Dictionary<Type, Feed>();
之后,您不需要注册方法。 检索单身人士时,应自动填写字典。
现在我假设你的Feed类有一个没有参数的默认构造函数。在这种情况下,您可以直接从抽象类Feed实现工厂方法。我们将在这里使用一些泛型,因为它允许您控制继承:
public abstract class Feed
{
public static T GetInstance<T>() where T:Feed, new()
{
T instance = new T();
// TODO: Implement here other initializing behaviour
return instance;
}
}
现在回到你的单身人士资料库。
public class FeedSingletonRepository
{
private static readonly object _padlock = new object();
private static Dictionary<Type, Feed> _singletons = new Dictionary<Type, Feed>();
public static T GetFeed<T>() where T:Feed
{
lock(_padlock)
{
if (!_singletons.ContainsKey(typeof(T))
{
_singletons[typeof(T)] = Feed.GetInstance<T>();
}
return (T)_singletons[typeof(T)];
}
}
}
请注意,我包含了一个线程安全行为,当您使用单身时,这是一件好事。
现在,如果你想获得继承自Feed
的给定类型的单例(让我们称之为SpecializedFeedType
),你所要做的就是:
var singleton = FeedSingletonRepository.GetFeed<SpecializedFeedType>();
或
SpecializedFeedType singleton = FeedSingletonRepository.GetFeed();
这是同一行,语法略有不同。
Edit2:更改了一些语法错误。
答案 1 :(得分:6)
正如旁注 - 作为工厂旨在包装创作,您正在创建对象并在工厂注册它们是一个奇怪的选择。这是一个对象存储库而不是工厂,还是比我看到的更多?
如果它是一个对象存储库,那么您可能还会在其他问题中找到一些额外的灵感,例如this one。
答案 2 :(得分:1)
调用RegisterFeed
方法时,需要传递Feed
类的具体实例。因此调用者有责任提供具体的实现。
答案 3 :(得分:1)
只需注册要创建的类的类型,然后使用Activator.CreateInstance
创建该类型的实例。
它应该以这种方式工作:
private static Type[] _factory = new Type[(int)FeedType.Total];
public void RegisterFeed(FeedType feedType, Type type)
{
...
_factory[(int)feedType] = type;
...
}
public Feed GetFeed(FeedType feedType)
{
return Activator.CreateInstance(_factory[(int)feedType]) as Feed;
}
您可以按以下方式致电RegisterFeed
:
RegisterFeed(FeedType.SomethingSpecial, typeof(MyDerivedSpecialFeed));
答案 4 :(得分:0)
class FeedFactory {
public IFeedFactory GetFeedFactory(string type) {
switch(type) {
case "1": return new Feed1(); break;
case "2": return new Feed2(); break;
}
}
}
注意所有Feeds必须实现IFeedFactory接口并实现必要的方法。
//来自客户端
FeedFactory ff1 = new FeedFactory();
IFeedFactory obj = ff1.GetFeedFactory("1");
obj.ExecuteMethod();