设计模式C#实现(十三)——享元模式(蝇量模式)

 

 

意图

运用共享技术有效地支持大量细粒度的对象。

适用性

当以下情况都成立时使用:

  • 一个程序使用了大量的对象
  • 完全由于使用大量对象造成很大存储开销
  • 对象的大多数状态都可以变为外部状态
  • 如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象
  • 应用程序不依赖对象标识

结构

蝇量UML
以下摘自参考1

享元模式采用一个共享来避免大量拥有相同内容对象的开销。这种开销最常见、最直观的就是内存的损耗。享元对象能做到共享的关键是区分内蕴状态(Internal State)和外蕴状态(External State)。
  一个内蕴状态是存储在享元对象内部的,并且是不会随环境的改变而有所不同。因此,一个享元可以具有内蕴状态并可以共享。
  一个外蕴状态是随环境的改变而改变的、不可以共享的。享元对象的外蕴状态必须由客户端保存,并在享元对象被创建之后,在需要使用的时候再传入到享元对象内部。外蕴状态不可以影响享元对象的内蕴状态,它们是相互独立的。

实现

现在用程序模拟各种果树,假设树龄是果树的外部状态,而果树的种类是果树的内部状态。
先来实现抽象果树,它有一个方法,这个方法依靠外部状态——树龄

  public abstract class Tree
    {
        protected string Type;

        public virtual void PrintDescription(int age)
        {
            Console.WriteLine(Type + ": " + age);
        }
    }

具体的果树,内部状态需要在实例化时传入

  public class ConcreteTree:Tree
    {
        public ConcreteTree(string type)
        {
            Type = type;
        }
    }

果树工厂负责创建和管理享元角色

   public class TreeFactory
    {
        private Dictionary<string, Tree> _trees = new Dictionary<string, Tree>();

        public Tree GetTree(string type)//获取对象
        {
            Tree tree;
            var result = _trees.TryGetValue(type, out tree);//查找该类型对象是否存在
            if (!result)
            {
                tree = new ConcreteTree(type);//不存在则实例化对象
                _trees.Add(type, tree);
            }
            return tree;
        }
    }

客户类

 class Program
    {
        static void Main(string[] args)
        {
            var factory = new TreeFactory();
            var tree1 = factory.GetTree("AppleTree");
            tree1.PrintDescription(10);
            var tree2 = factory.GetTree("PeerTree");
            tree2.PrintDescription(12);
            var tree3 = factory.GetTree("AppleTree");
            tree3.PrintDescription(8);
            Console.WriteLine(tree1==tree3);
            Console.ReadKey();
        }
    }

运行结果
运行结果
从结果看,tree1和tree3是同一个对象实例,因此当我们有大量的同类果树时,只需要维护一个实例对象和一个树龄数组从而节省了存储空间。

效果

  • 节省存储空间
  • 逻辑比直接维护多个实例复杂

参考

  1. 《JAVA与模式》之享元模式
  2. 《Head First 设计模式》
  3. 《设计模式》
posted @ 2015-12-20 18:13  妖刀Dreamcast  阅读(408)  评论(0编辑  收藏  举报