Aks*_*Aks 4 c# design-patterns factory repository
我正在实现一个看起来如下的工厂模式.
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];
}
}
Run Code Online (Sandbox Code Playgroud)
这Feed是一个抽象类,不同的类从中继承.如何注册不同的课程?是否有可能从他们的构造函数中做到这一点?
这不是工厂模式.工厂总是会有一些构造函数逻辑,至少有一个new.这就是工厂的想法:调用者不必担心如何创建对象.这是一个单例存储库.
首先,您应该使用类型索引字典,而不是使用数组.
private static Dictionary<Type, Feed> _singletons = new Dictionary<Type, Feed>();
Run Code Online (Sandbox Code Playgroud)
之后,您不需要注册方法.检索单例时,应自动填充字典.
现在我假设你的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;
}
}
Run Code Online (Sandbox Code Playgroud)
现在回到你的单例存储库.
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)];
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,我包含了一个线程安全行为,当您使用单例时,这是一件好事.
现在,如果你想获得继承的给定类型的单例Feed(让我们调用它SpecializedFeedType),你所要做的就是:
var singleton = FeedSingletonRepository.GetFeed<SpecializedFeedType>();
Run Code Online (Sandbox Code Playgroud)
要么
SpecializedFeedType singleton = FeedSingletonRepository.GetFeed();
Run Code Online (Sandbox Code Playgroud)
这是同一行,语法略有不同.
Edit2:更改了一些语法错误.