首页 > 设计模式 > 初尝Flyweight 模式

初尝Flyweight 模式

面向对象很好的解决了抽象的问题,在大多数的情况下也不会影响到系统性能。但,当对象的数量级达到一定的时候,过多的对象会给系统内存带来难以承受的开销。比如文字处理中的字符。

Flyweight在牛津字典中的解释是”boxer of the lightest class”。(意思是轻量级拳击手)。在这里其实应该是取”the lightest class”这部份的解释,一个特轻量级类别,这个类别所产生的对象可以共用在每一个场合(context),并依场合表现其外蕴。这里根据其具体表达形式,翻译为享元模式。

享元模式以共享的方式高效地支持大量的细粒度对象。享元对象能做到共享的关键是区分内蕴状态(Internal State)和外蕴状态(External State)。内蕴状态是存储在享元对象内部并且不会随环境改变而改变。因此内蕴状态并可以共享

外蕴状态是随环境改变而改变的、不可以共享的状态。享元对象的外蕴状态必须由客户端保存,并在享元对象被创建之后,在需要使用的时候再传入到享元对象内部。外蕴状态与内蕴状态是相互独立的

意图:

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

单纯享元模式结构图:

单纯Flyweight结构图 初尝Flyweight 模式

复合享元模式结构图:

复合Flyweight结构图 初尝Flyweight 模式

其中尤其需要指出的是FlyweightFactory 这个角色负责创建和管理享元角色。本角色必须保证享元对象可以被系统适当地共享。当一个客户端对象请求一个享元对象的时候,享元工厂角色需要检查系统中是否已经有一个符合要求的享元对象,如果已经有了,享元工厂角色就应当提供这个已有的享元对象;如果系统中没有一个适当的享元对象的话,享元工厂角色就应当创建一个新的合适的享元对象。

一段代码

using System;
using System.Collections;

namespace Flyweight
{
    public class CoffeeServer
    {
        private string flavor;//内蕴状态(Internal State)
        public CoffeeServer(string flavor)
        {
            this.flavor = flavor;
        }
        public void Serve(Table table)
        {
            Console.WriteLine("Table {0} Getting flavor {1}!", table.Number, this.flavor);
        }
    }

    public class CoffeeFactory
    {
        public Hashtable coffees = new Hashtable();
        public CoffeeServer GetCoffee(string key)
        {
            if (!coffees.Contains(key))
                coffees.Add(key, new CoffeeServer(key));
            return (CoffeeServer)coffees[key];
        }
        public int GetTotalNum()
        {
            return coffees.Count;
        }

    }
    //外蕴状态 (External State)
    public class Table
    {
        private int number;
        public Table(int number)
        {
            this.number = number;
        }
        public int Number
        {
            get
            {
                return this.number;
            }
        }
    }

    class Program
    {
        static int OrderNum = 0;
        static CoffeeFactory factory = new CoffeeFactory();
        static void Main(string[] args)
        {
            //发出7个订单,但实际上只使用了4种咖啡
            Order("Black Coffee");
            Order("Black Coffee");
            Order("Cappuccino");
            Order("Cappuccino");
            Order("Cappuccino");
            Order("Espresso");
            Order("Coffee");
            Console.WriteLine("Order Number :{0}", OrderNum);
            Console.WriteLine("Coffee Number :{0}", factory.GetTotalNum());
        }

        public static void Order(string flavor)
        {
            CoffeeServer coffee = factory.GetCoffee(flavor);
            coffee.Serve(new Table(OrderNum));
            OrderNum++;
        }
    }
}
运行截图
Flyweight运行截图 初尝Flyweight 模式
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.