设计模式之日志工厂
中提到了非常典型的工厂模式生产对象实例,但是但是工厂模式后期呢?
好吧,我们经常见到Provider,XXXProvider,是的没错提供器,干什么的,通过看Supersocket源代码发现在大量工厂模式身后不断涌现出Provider这个神奇的东西,来看代码
1 [Serializable] 2 public class ProviderFactoryInfo 3 { 4 /// <summary> 5 /// Gets the key. 6 /// </summary> 7 public ProviderKey Key { get; set; } 8 9 /// <summary> 10 /// Gets or sets the name. 11 /// </summary> 12 /// <value> 13 /// The name. 14 /// </value> 15 public string Name { get; set; } 16 17 18 /// <summary> 19 /// Gets or sets the export factory. 20 /// </summary> 21 /// <value> 22 /// The export factory. 23 /// </value> 24 public ExportFactory ExportFactory { get; set; } 25 26 /// <summary> 27 /// Initializes a new instance of the <see cref="ProviderFactoryInfo"/> class. 28 /// </summary> 29 public ProviderFactoryInfo() 30 { 31 32 } 33 34 /// <summary> 35 /// Initializes a new instance of the <see cref="ProviderFactoryInfo"/> class. 36 /// </summary> 37 /// <param name="key">The key.</param> 38 /// <param name="name">The name.</param> 39 /// <param name="instance">The instance.</param> 40 public ProviderFactoryInfo(ProviderKey key, string name, object instance) 41 { 42 Key = key; 43 Name = name; 44 ExportFactory = new ExportFactory(instance); 45 } 46 47 /// <summary> 48 /// Initializes a new instance of the <see cref="ProviderFactoryInfo"/> class. 49 /// </summary> 50 /// <param name="key">The key.</param> 51 /// <param name="name">The name.</param> 52 /// <param name="typeName">Name of the type.</param> 53 public ProviderFactoryInfo(ProviderKey key, string name, string typeName) 54 { 55 Key = key; 56 Name = name; 57 ExportFactory = new ExportFactory(typeName); 58 } 59 60 /// <summary> 61 /// Initializes a new instance of the <see cref="ProviderFactoryInfo"/> class. 62 /// </summary> 63 /// <param name="key">The key.</param> 64 /// <param name="name">The name.</param> 65 /// <param name="type">The type.</param> 66 public ProviderFactoryInfo(ProviderKey key, string name, Type type) 67 : this(key, name, type.AssemblyQualifiedName) 68 { 69 70 } 71 }
ProviderFactoryInfo类向外一些属性,其中非常重要的属性ExportFactory导出工厂,好吧他是干什么的呢?
从名字上简单理解一下,应该是导出一个类型的实例吧,没错就是这么简单,在这里是不是已经嗅到一股适配器模式的感觉,个人觉得还基本上差不多,来看ExportFactory代码
1 [Serializable] 2 public class ExportFactory 3 { 4 /// <summary> 5 /// Gets or sets the type. 6 /// </summary> 7 /// <value> 8 /// The type. 9 /// </value> 10 public string TypeName { get; set; } 11 12 private Type m_LoadedType; 13 14 [NonSerialized] 15 private object m_Instance; 16 17 /// <summary> 18 /// Initializes a new instance of the <see cref="ExportFactory"/> class. 19 /// </summary> 20 public ExportFactory() 21 { 22 23 } 24 25 /// <summary> 26 /// Initializes a new instance of the <see cref="ExportFactory"/> class. 27 /// </summary> 28 /// <param name="instance">The instance.</param> 29 public ExportFactory(object instance) 30 { 31 m_Instance = instance; 32 } 33 34 /// <summary> 35 /// Initializes a new instance of the <see cref="ExportFactory"/> class. 36 /// </summary> 37 /// <param name="typeName">Name of the type.</param> 38 public ExportFactory(string typeName) 39 { 40 TypeName = typeName; 41 } 42 43 /// <summary> 44 /// Ensures the instance's existance. 45 /// </summary> 46 public void EnsureInstance() 47 { 48 if (m_Instance != null) 49 return; 50 51 m_Instance = CreateInstance(); 52 } 53 54 private object CreateInstance() 55 { 56 if (m_LoadedType == null) 57 { 58 m_LoadedType = AssemblyUtil.GetType(TypeName, true, true); 59 } 60 61 return Activator.CreateInstance(m_LoadedType); 62 } 63 64 /// <summary> 65 /// Creates the export type instance. 66 /// </summary> 67 /// <typeparam name="T"></typeparam> 68 /// <returns></returns> 69 public T CreateExport<T>() 70 { 71 if (m_Instance != null) 72 return (T)m_Instance; 73 74 return (T)CreateInstance(); 75 } 76 77 /// <summary> 78 /// Creates the export type instance from the instance creator. 79 /// </summary> 80 /// <typeparam name="T"></typeparam> 81 /// <param name="creator">The creator.</param> 82 /// <returns></returns> 83 public T CreateExport<T>(Func<Type, object> creator) 84 { 85 if (m_LoadedType == null) 86 { 87 m_LoadedType = AssemblyUtil.GetType(TypeName, true, true); 88 } 89 90 return (T)creator(m_LoadedType); 91 } 92 }
该类向外部暴露了非常核心的重要方法,也是其主要职能的方法 public T CreateExport<T>(),创建一个实例,且是一个泛型方法,意思说创建一个给定类型的实例;读到这里在联系Provider,这个东西,
既然他封装了一个这个ExportFactory,意思就说明给我一个什么类型 我就创建什么实例,好吧工厂的实例就可以这样被创建出来了,那么创建什么类型可以通过 public ProviderKey Key { get; set; }属性来指定是不是很方便,
从此处可以看出Provider的存在主要解决一些类型适配问题,通过反射创建任意类型的实例,对于工厂模式来说是一种补充
总结
1 工厂模式的优势在于创建对象与new分离,提高了代码的扩展能力,比如我想自定义一个则直接实现一个工厂即可
2 Provider的优势在于适配,灵活的构建各种对象,在扩展能力方面更起到非常大的作用