设计模式之工厂模式大后期

设计模式之日志工厂

中提到了非常典型的工厂模式生产对象实例,但是但是工厂模式后期呢?

好吧,我们经常见到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     }
View Code

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     }
View Code

该类向外部暴露了非常核心的重要方法,也是其主要职能的方法 public T CreateExport<T>(),创建一个实例,且是一个泛型方法,意思说创建一个给定类型的实例;读到这里在联系Provider,这个东西,

既然他封装了一个这个ExportFactory,意思就说明给我一个什么类型 我就创建什么实例,好吧工厂的实例就可以这样被创建出来了,那么创建什么类型可以通过 public ProviderKey Key { get; set; }属性来指定是不是很方便,

从此处可以看出Provider的存在主要解决一些类型适配问题,通过反射创建任意类型的实例,对于工厂模式来说是一种补充

总结

1 工厂模式的优势在于创建对象与new分离,提高了代码的扩展能力,比如我想自定义一个则直接实现一个工厂即可

2 Provider的优势在于适配,灵活的构建各种对象,在扩展能力方面更起到非常大的作用

原文地址:https://www.cnblogs.com/rjjs/p/5614735.html