一個簡單的 Generic Factory 類

來源:互聯網
上載者:User

簡單的工廠類的一個使用情境是, 假設有一個基類 BaseClass, 和一系列的子類 A, B, C, 工廠類根據某個參數,例如字串 “A”, “B”, “C” 建立出相應的子類。 舉例如下:

public class Factory{    public static BaseClass Create(string name)    {        switch (name)        {            case "A": return new A();            case "B": return new B();            case "C": return new C();            default: throw new ArgumentException("Wrong Name");        }    }}

這裡的一個問題是, 當子類增加或減少時, Factory 類 需要相應的改動。 有沒有辦法可以只是改動子類本身, 而不用修改Factory類呢, 當然有,這裡我舉一個簡單的實現。

基本思想是在每個子類上附加一個 Attribute, 定義如下:

[AttributeUsage(AttributeTargets.Class)]public class FactoryKeyAttribute : Attribute{    public object Key { get; set; }}

假設我們有基類和子類實現如下

public abstract class BaseClass {}[FactoryKey(Key = "Standard")]public class Standard : BaseClass {}[FactoryKey(Key = "Enterprise")]public class Enterprise : BaseClass {}[FactoryKey(Key = "Lite")]public class Lite : BaseClass {}

 

假設這些類都在同一個 Assembly中 (對於不在同一個Assembly的,實現會稍微複雜些)工廠類需要積極式載入 Key => Type 的Mapping, 然後根據Key建立不同的執行個體, 實現如下:

public class Factory<TKey, TBaseClass>{    private static readonly IDictionary<TKey, Type> TypeDict = Init();    private static IDictionary<TKey, Type> Init()    {        var dict = from type in Assembly.GetExecutingAssembly().GetTypes()                   let key = (FactoryKeyAttribute)Attribute.GetCustomAttribute(type, typeof(FactoryKeyAttribute))                   where key != null && typeof(TBaseClass).IsAssignableFrom(type)                   select new { Key = key, Value = type };        return dict.ToDictionary(kvp => (TKey)kvp.Key.Key, kvp => kvp.Value);    }    public static TBaseClass CreateInstance(TKey key)    {        Type type;        if (TypeDict.TryGetValue(key, out type))        {            return (TBaseClass)Activator.CreateInstance(type);        }        throw new ArgumentException("Incorrect Key!");    }}

使用方法也很簡單:

BaseClass s = Factory<string, BaseClass>.CreateInstance("Standard");BaseClass l = Factory<string, BaseClass>.CreateInstance("Lite");BaseClass e = Factory<string, BaseClass>.CreateInstance("Enterprise");

 

對於其他類型的Key,比如 Enum, 或其他類型的基類, 改變Factory 的型別參數即可。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.