簡體   English   中英

C#中的工廠模式實現

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM