定义:运用共享技术有效支持大量细粒度的对象

有一个享元工厂,用来创建并管理flyweight对象。它主要是确保合理共享flyweight,当用户请求一个flyweight时,flyweight工厂对象提供一个已知创建的实例或者创建一个

内部状态和外部状态:

在享元对象内部并且不会随环境变化而变化的共享状态,是享元对象的内部状态

随环境改变而改变的,不可以共享的状态是外部状态

使用情景:

如果一个应用程序使用了大量的对象,而大量对象造成了很大的存储开销;对象的大多数状态可以用外部状态,如果删除对象外部,那么可以用相对较少的共享对象取代很多组对象

e.g. String的存储

using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
namespace 享元模式
{
    class Program
    {
        public class Student
        {
            private string name;
            public Student(string name)
            {
                this.name = name;
            }
            public string Name
            {
                get { return name; }
            }
        }
        abstract class Paper
        {
            public abstract void Read(Student student);
        }
        class ConcretePaper:Paper
        {
            private string name = "";
            public ConcretePaper(string name)
            {
                this.name = name;
            }
            public override void Read(Student stu)
            {
                Console.WriteLine("paper class: " + name + " stu: " + stu.Name);
            }
        }
        class PaperFactory
        {
            private Hashtable stuMap = new Hashtable();
            public Paper GetPaperClass(string key)
            {
                if (!stuMap.ContainsKey(key))
                    stuMap.Add(key, new ConcretePaper(key));
                return ((Paper)stuMap[key]);
            }
            public int GetPaperCount()
            {
                return stuMap.Count;
            }
        }
        static void Main(string[] args)
        {
            PaperFactory f = new PaperFactory();
            Paper x = f.GetPaperClass("xxx");
            x.Read(new Student("01"));
            Paper y = f.GetPaperClass("yyy");

            y.Read(new Student("02"));
            Paper z = f.GetPaperClass("xxx");
            z.Read(new Student("03"));
            Paper a = f.GetPaperClass("yyy");
            a.Read(new Student("04"));
            Paper b = f.GetPaperClass("xxx");
            b.Read(new Student("05"));
            Paper c = f.GetPaperClass("yyy");
            c.Read(new Student("06"));
            Console.WriteLine("classCount:" + f.GetPaperCount());
            Console.Read();
        }
    }
}

paper class: xxx stu: 01
paper class: yyy stu: 02
paper class: xxx stu: 03
paper class: yyy stu: 04
paper class: xxx stu: 05
paper class: yyy stu: 06
classCount:2