public interface IFactory<T> { T Create(); } 這個工廠生產一個T類型的對象。當你實現此工廠時,應該讓T為抽象產品的類型——即產品通用的基類。比如我們可以實現一個采用無參數構造函數來創建對象的OpNewFactory實現:
public class OpNewFactory<TAbstractPRodUCt, TProduct> : IFactory<TAbstractProduct> where TProduct : TAbstractProduct, new() { public TAbstractProduct Create() { return new TProduct(); } } 從此例子可以看出,你應該僅實現抽象類型的IFactory接口,并生成具體類型?,F在我們做完了單一產品的工廠方法模板,就要開始定義生產多個產品的抽象工廠接口了。.NET泛型支持按類型參數個數進行重載,就是說,我們可以定義生產一個、兩個、三個……等多種數目的抽象工廠接口,而使用同一個名字。(汗吧,這就是所謂支持“任意數目”的手法)這里免不了要拷貝代碼,不過別擔心,純拷貝而已,使用的時候可是非常舒心的哦。我們以生產兩種產品類型的抽象工廠為例介紹。能不能定義成這樣呢?
public sealed class TypeToken<T> { static private TypeToken<T> instanceValue = new TypeToken<T>(); static public TypeToken<T> Instance { get { return instanceValue; } }
public T1 Create(TypeToken<T1> token) { return factory1.Create(); }
public T2 Create(TypeToken<T2> token) { return factory2.Create(); } }
public static class ConcretFactory { public static ConcreteFactory<T1, T2> NewFactory<T1, T2>(IFactory<T1> f1, IFactory<T2> f2) { return new ConcreteFactory<T1, T2>(f1, f2); } } 注重,我又聲明了一個沒有類型參數的ConcretFactory類,用一個靜態方法來生成泛型ConcretFactory的實例,這是因為使用泛型方法可以推測類型參數,使得我們可以不必輸入尖括號或Of語句,而泛型類則沒有這個功能?,F在大功告成!我們用一個例子來演示這個泛型抽象工廠的工作情況?,F在假設我們需要一個生產PC的抽象工廠,需要生產兩種抽象產品:處理器和內存。處理器和內存的抽象和具體實現如下:
Processor 和 Ram public abstract class Processor { public abstract string Model { get; } }
public abstract class Ram { public abstract int Frequency { get;} }
public class PentiumProcessor : Processor { public override string Model { get { return "Pentium Extreme Edition 955"; } } }
public class AthlonProcessor : Processor { public override string Model { get { return "Athlon 64 X2 FX-60"; } } }
public class DDRRam : Ram { public override int Frequency { get { return 400; } } }
public class DDR2Ram : Ram { public override int Frequency { get { return 533; } } } 下面的代碼演示了如何隨心所欲生成想要的抽象工廠接口以及快速從現有單一產品工廠組合成特定的具體工廠實現。
class Program { static IAbstractFactory<Processor, Ram> ComputerFactory(string type) { if (type == "Intel") { return ConcretFactory.NewFactory( new OpNewFactory<Processor, PentiumProcessor>(), new OpNewFactory<Ram, DDR2Ram>()); } else if (type == "AMD") { return ConcretFactory.NewFactory( new OpNewFactory<Processor, AthlonProcessor>(), new OpNewFactory<Ram, DDRRam>()); }
//unknown type return null; }
static void Main(string[] args) { //Yield a computer of Intel IAbstractFactory<Processor, Ram> factory1 = ComputerFactory("Intel");