[英]Factory Pattern implementation in C#
我正在實現一個看起來如下的工廠模式。
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
是一個抽象類,不同的類從中繼承。 如何注冊不同的課程? 是否有可能從他們的構造函數中做到這一點?
這不是工廠模式。 工廠總是會有一些構造函數邏輯,至少有一個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:更改了一些語法錯誤。
正如旁注 - 作為工廠旨在包裝創作,您正在創建對象並將其注冊到工廠是一個奇怪的選擇。 這是一個對象存儲庫而不是工廠,還是比我看到的更多的類?
如果它是一個對象存儲庫,那么您可能還會在其他問題中找到一些額外的靈感,比如這個問題。
當您調用RegisterFeed
方法時,您需要傳遞Feed
類的具體實例。 因此調用者有責任提供具體的實現。
只需注冊要創建的類的類型,然后使用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));
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();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.