享元(Flyweight)模式:运用共享技术有效的支持大量细粒度的对象。
/*
* 抽象享元(Flyweight)角色:此角色是所有的具体享元类的超类,为这些类规定出需要实现的公共接口。
那些需要外蕴状态(External State)的操作可以通过调用商业方法以参数形式传入。
* 具体享元(ConcreteFlyweight)角色:实现抽象享元角色所规定的接口。如果有内蕴状态的话,必须负责为内蕴状态提供存储空间。
享元对象的内蕴状态必须与对象所处的周围环境无关,从而使得享元对象可以在系统内共享的。
* 享元工厂(FlyweightFactory)角色:本角色负责创建和管理享元角色。本角色必须保证享元对象可以被系统适当地共享。
当一个客户端对象调用一个享元对象的时候,享元工厂角色会检查系统中是否已经有一个复合要求的享元对象。
如果已经有了,享元工厂角色就应当提供这个已有的享元对象;如果系统中没有一个适当的享元对象的话,享元工厂角色就应当创建一个合适的享元对象。
* 客户端(Client)角色:本角色需要维护一个对所有享元对象的引用。本角色需要自行存储所有享元对象的外蕴状态。
*/
享元模式,当你使用的是相同对象的时候,就直接使用已经存在的对象,不用再去创建一个相同的对象。
一个咖啡店例子
抽象享元(Flyweight):Order 提供对咖啡的一些动作
具体享元(ConcreteFlyweight):Flavor 实现卖咖啡,以及返回咖啡名称。GetFlavor() GetFlavor();
享元工厂(FlyweightFactory): FlavorFactory则对咖啡进行判断,如果重复的咖啡,就没必要新建,只要在类型上数量相加就好。所以方法返回的是一个共享的 具体享元角色。
Console.WriteLine(" =====咖啡销售机===== "); flavorFactory = new FlavorFactory(); TakeOrder("Black Coffee"); TakeOrder("Capucino"); TakeOrder("Espresso"); TakeOrder("Capucino"); TakeOrder("Espresso"); TakeOrder("Black Coffee"); TakeOrder("Espresso"); TakeOrder("Espresso"); TakeOrder("Black Coffee"); TakeOrder("Capucino"); TakeOrder("Capucino"); TakeOrder("Black Coffee"); Console.WriteLine(" 总共卖出多少份 : " + ordersMade); Console.WriteLine(" 风格品种 : " + flavorFactory.GetTotalFlavorsMade()); private static void TakeOrder(string aFlavor) { Order o = flavorFactory.GetOrder(aFlavor); // 将咖啡卖给客人 o.Serve(); ordersMade++; } /// <summary> /// 抽象享元(Flyweight)角色 /// </summary> public abstract class Order { // 将咖啡卖给客人 public abstract void Serve(); // 返回咖啡的名字 public abstract string GetFlavor(); } /// <summary> /// 具体享元(ConcreteFlyweight)角色 /// </summary> public class Flavor : Order { private string flavor; // 构造函数,内蕴状态以参数方式传入 public Flavor(string flavor) { this.flavor = flavor; } // 返回咖啡的名字 public override string GetFlavor() { return this.flavor; } // 将咖啡卖给客人 public override void Serve() { Console.WriteLine("卖出咖啡- " + flavor); } } /// <summary> /// 享元工厂(FlyweightFactory)角色 /// </summary> public class FlavorFactory { private Hashtable flavors = new Hashtable(); public Order GetOrder(string key) { if (!flavors.ContainsKey(key)) flavors.Add(key, new Flavor(key)); return ((Order)flavors[key]); } public int GetTotalFlavorsMade() { return flavors.Count; } }
基本代码:
//变量赋值 int extrinsicstate = 22; FlyweightFactory f = new FlyweightFactory(); // 使用不同的轻量级选手实例 Flyweight fx = f.GetFlyweight("X"); fx.Operation(--extrinsicstate); Flyweight fy = f.GetFlyweight("Z"); fy.Operation(--extrinsicstate); Flyweight fz = f.GetFlyweight("Y"); fz.Operation(--extrinsicstate); /// <summary> /// 抽象享元(Flyweight)角色 /// </summary> public abstract class Flyweight { // 方法 public abstract void Operation(int extrinsicstate); } /// <summary> /// 具体享元(ConcreteFlyweight)角色 /// </summary> public class ConcreteFlyweight : Flyweight { private string intrinsicstate = "A"; public override void Operation(int extrinsicstate) { Console.WriteLine("ConcreteFlyweight1: 级别- {0}, 编号- {1}", intrinsicstate, extrinsicstate); } } /// <summary> /// 具体享元(ConcreteFlyweight)角色 /// </summary> public class ConcreteFlyweight2 : Flyweight { private string intrinsicstate = "B"; public override void Operation(int extrinsicstate) { Console.WriteLine("ConcreteFlyweight2: 级别- {0}, 编号- {1}", intrinsicstate, extrinsicstate); } } /// <summary> /// 享元工厂(FlyweightFactory)角色 /// </summary> public class FlyweightFactory { private Hashtable flyweights = new Hashtable(); // 构造函数 public FlyweightFactory() { flyweights.Add("X", new ConcreteFlyweight()); flyweights.Add("Y", new ConcreteFlyweight2()); flyweights.Add("Z", new ConcreteFlyweight()); } // 方法 public Flyweight GetFlyweight(string key) { return ((Flyweight)flyweights[key]); } }