工厂方法模式就是把该类的实例化过程延迟到子类,将new工作交给工厂完成,同时对工厂自身进行抽象,然后客户端程序基于工厂的抽象行为构造所需的实例类型
/// <summary> /// 抽象产品类型 /// </summary> public interface IProduct { string Name { get;} // 约定的抽象产品所必须具有的特征 } /// <summary> /// 具体产品类型 /// </summary> public class ProductA : IProduct { public string Name { get { return "A"; } } } /// <summary> /// 具体产品类型 /// </summary> public class ProductB : IProduct { public string Name { get { return "B"; } } } //抽象工厂类 public interface IFactory { IProduct Creat(); } //两个具体工厂类型 public class FactoryA : IFactory { public IProduct Creat() { return new ProductA(); } } public class FactoryB: IFactory { public IProduct Creat() { return new ProductB(); } }
调用
class Client { public void Test() { IFactory factory = new FactoryA(); IProduct product = factory.Creat(); } }
但是这么做还是会让客户端程序来new一个Factroy,Factroy依赖产品,还是会形成间接依赖产品,这样又粘连了在一起,背离了设计模式,所以我们要解除这一层的粘连
靠依赖注入来解决这个问题,把客户端的IFactory给它注入进去,看完整代码
/// <summary> /// 抽象产品类型 /// </summary> public interface IProduct { string Name { get;} // 约定的抽象产品所必须具有的特征 } /// <summary> /// 具体产品类型 /// </summary> public class ProductA : IProduct { public string Name { get { return "A"; } } } /// <summary> /// 具体产品类型 /// </summary> public class ProductB : IProduct { public string Name { get { return "B"; } } } //抽象工厂类 public interface IFactory { IProduct Creat(); } //两个具体工厂类型 public class FactoryA : IFactory { public IProduct Creat() { return new ProductA(); } } public class FactoryB : IFactory { public IProduct Creat() { return new ProductB(); } }
Assembler
//依赖注入 class Client { public IFactory Factory { get; set; } public IProduct Product { get { return Factory.Creat(); } } } public class Assembler { /// <summary> /// 保存“抽象类型/实体类型”对应关系的字典 /// </summary> static Dictionary<Type, Type> dictionary = new Dictionary<Type, Type>(); static Assembler() { // 注册抽象类型需要使用的实体类型 // 实际的配置信息可以从外层机制获得,例如通过配置定义. dictionary.Add(typeof(IFactory), typeof(FactoryA)); } /// <summary> /// 根据客户程序需要的抽象类型选择相应的实体类型,并返回类型实例 /// </summary> /// <typeparam name="T">抽象类型(抽象类/接口/或者某种基类)</typeparam> /// <returns>实体类型实例</returns> public object Create(Type type) // 主要用于非泛型方式调用 { if ((type == null) || !dictionary.ContainsKey(type)) throw new NullReferenceException(); Type targetType = dictionary[type]; return Activator.CreateInstance(targetType); } /// <typeparam name="T">抽象类型(抽象类/接口/或者某种基类)</typeparam> public T Create<T>() // 主要用于泛型方式调用 { return (T)Create(typeof(T)); } public void Assembly(Client client) { client.Factory = Create<IFactory>(); } }
调用
public class Test { public void FactoryWithAsembly() { var client = new Client(); new Assembler().Assembly(client); //这次client。Factory与Product都被赋值了 } }
这里作者没有给出例子,我自己按照前面的代码写出来,感觉Assembler主要依靠一个字典集合,然后根据T类型来映射,从而直接给出对象,不知道作者是否是这个本意,我目前是这么理解的,希望以后有机会能够请教下作者