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接口,并生成具体类型。现在我们做完了单一产品的工厂方法模板,就要开始定义生产多个产品的抽象工厂接口了。.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语句,而泛型类则没有这个功能。现在大功告成!我们用一个例子来演示这个泛型抽象工厂的工作情况。现在假设我们需要一个生产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");