定义

  1. 运用共享技术有效地支持大量细粒度的对象
  2. 通俗一点来说,即相同对象同享使用,而不是反复创建多个相同的东西
  3. 如果需要生成大量细粒度的类实例来表示数据,如果发现这些实例除了几个基本参数外基本相同,有时能大幅度减少类实例的数量,如果能把这些参数移动到类实例外面,然后通过方法传递进来,就可以通过共享大幅度减少单个实例的数目

使用场景

  1. c#中的string字符串,例如有两个字符串都是 “张三”,那么这两个地址都指向一个存储张三的区域,而不会创建两个区域来储存张三
  2. 游戏场景中,创建多个相同的敌人
  3. 围棋或五子棋游戏中,创建黑白棋,只有颜色和位置不同,其他属性是一样的
  4. 在多个重复对象使用中,使用享元模式,如果重复对象较少,则没必要使用

代码实现

//享元抽象类
abstract class FlyWeight
{
      public abstract void Operation(int extrinsticState);
}

class ConcreteFlyWeight: FlyWeight
{
    public override void Operaion(int extrinsticState)
    {
        Console.WriteLine("具体 FlyWeight:{0}", extrinsticState);
    }
}

class UnsharedConcreteFlyWeight: FlyWeight
{
    public override void Operation(int extrinsticState)
    {
         Console.WriteLine("不共享的具体 FlyWeight:{0}", extrinsticState);
    }
}


//享元工厂
class FlyWeightFactory
{
     private Hashtable flyWeights = new Hashtable(); //存储享元元素

     public FlyWeightFactory()
     {
           flyWeights.Add("X", new ConcreteFlyWeight());
           flyWeights.Add("Y", new ConcreteFlyWeight());
           flyWeights.Add("Z", new ConcreteFlyWeight()); 
     }
    
     public FlyWeight GetFlyWeight(string key)
     {
           return (FlyWeight)flyWeights[key];
     }

}


void Main()
{
    int extrinsticState = 22; //外部参数

    FlyWeightFactory factory = new FlyWeightFactory();
    
    FlyWeight fx = factory.GetFlyWeight("X");
    fx.Operation(--extrinstic);
    
    FlyWeight fy = factory.GetFlyWeight("Y");
    fy.Operation(--extrinstic);
    
    FlyWeight fz = factory.GetFlyWeight("Z");
    fz.Operation(--extrinstic);
    
     UnsharedConcreteFlyWeight uf = new UnsharedConcreteFlyWeight();
     uf.Operation(--extrinsticState);

}

优点缺点

  1. 享元模式可以大幅度减少非常相似类的开销,大大减少了对象的创建,降低系统内存,使效率更高
  2. 提高了系统复杂度,需要分离外部状态和内部状态,而且外部状态具有固有化的性质,不应该随着内部状态的变化而变化,否则会造成系统的混乱,因为存在多个引用指向同一个对象的情况,要考虑每个对象的变化是否会影响到其他对象,如果影响到,说明还没有达到最细粒度