一、享元模式模式:享元模式是实现对象重用的一种方式,适用于为了尽可能的减少对象的重复创建而增大资源开销的情况,与单例模式有类似的作用。
二、实现思路 :对象被第一次创建后,如果后续还有可能使用该类对象,我们设法将创建后的对象保存为静态资源,后续需要时直接从静态资源中取出使用,常见的方式是使用一个工厂-享元工厂类负责管理对象,使用静态字典保存对象。
三、代码举例:
1、享元工厂类Factory:
namespace Flyweight { public class Factory { private static Dictionary<string, object> dir = new Dictionary<string, object>(); private static object _lock = new object(); public static object CreateObject(string objName) { object obj = null; if (dir.ContainsKey(objName)) { obj = dir[objName]; } else { lock (_lock)//用于多线程模式下也保证不重复创建 { if (dir.ContainsKey(objName)) { obj = dir[objName]; } else { switch (objName) { case "objectA": obj = new objectA(); break; case "objectB": obj = new objectB(); break; case "objectC": obj = new objectC(); break; default: throw new Exception("对象不明确!"); } dir.Add(objName, obj); } } } return obj; } } }
2、objectA类:
namespace Flyweight { public class objectA { public objectA() { Console.WriteLine("objectA被创建....."); } } }
3、objectB类:
namespace Flyweight { public class objectB { public objectB() { Console.WriteLine("objectB被创建....."); } } }
4、objectC类:
namespace Flyweight { public class objectC { public objectC() { Console.WriteLine("objectC被创建....."); } } }
5、客户类:
{ //享元模式 Flyweight.objectA A1 = (Flyweight.objectA)Flyweight.Factory.CreateObject("objectA"); Flyweight.objectA A2 = (Flyweight.objectA)Flyweight.Factory.CreateObject("objectA"); Flyweight.objectB B1 = (Flyweight.objectB)Flyweight.Factory.CreateObject("objectB"); Flyweight.objectB B2 = (Flyweight.objectB)Flyweight.Factory.CreateObject("objectB"); Flyweight.objectC C1 = (Flyweight.objectC)Flyweight.Factory.CreateObject("objectC"); Flyweight.objectC C2 = (Flyweight.objectC)Flyweight.Factory.CreateObject("objectC"); Console.WriteLine("A1与A2是否为同一实例?{0}", ReferenceEquals(A1, A2)); Console.WriteLine("B1与B2是否为同一实例?{0}", ReferenceEquals(B1, B2)); Console.WriteLine("C1与C2是否为同一实例?{0}", ReferenceEquals(C1, C2)); Console.WriteLine("............................."); Console.ReadKey(); }
6、运行结果:
四、享元模式的优缺点及应用:享元模式中对象的实例通过享元工厂自己管理,从工厂内部实现复用,保证对象不重复创建,而在工厂外部其他地方也可以实例化对象,这与单例不同,单例模式无法在内的外部实例化,从而保证了整个程序中只有一个实例(注意:clr运行时对字符串string类型也应用了享元模式,string str=“zhangshan”;这句话相当于sting str=new string(“zhangshan”);,使用该方式创建字符串,如果字符串值相等,则他们在内存中共享一块空间,变量都指向同一个内存地址)。