享元模式(Flyweight)
定义
享元模式(Flyweight),运用共享技术有效地支持大量细粒度的对象。
类图
描述
Flyweight:抽象享元类,是所有的具体享元类的基类,为子类规定出需要实现的公共接口。那些需要外部状态的操作可以通过调用Flyweight的方法并以参数的形式传入。
ConcreteFlyweight:具体享元类,实现抽象享元角色所规定的接口。如果有内部状态的话,可以在类内部定义。
FlyweightFactory:享元工厂,用来创建和管理享元对象,主要用来确保合理地共享Flyweight,当用户请求一个Flyweight时,FlyweightFactory对象提供一个已创建的实例或者创建一个(如果不存在的话)。
内部状态:是指在享元对象内部并且不会随环境改变而改变的共享部分,内部状态存储于ConcreteFlyweight对象中;
外部状态:是指随环境改变而改变、不可以共享的部分,外部状态存储于外部对象中,当调用Flyweight对象的操作时,将外部状态传递给Flyweight对象。
享元模式可以看作是一种最简单的缓存技术的实现。
应用场景
public class Student { private string name; public string Name { get { return name; } } public Student(string name) { this.name = name; } } public abstract class AbstractCourse { public abstract void Print(Student student); } public class Course : AbstractCourse { /// <summary> /// 课程名称 /// </summary> private string name; /// <summary> /// 课时 /// </summary> private int periods; public Course(string name, int periods) { this.name = name; this.periods = periods; } public override void Print(Student student) { Console.WriteLine(student.Name + ": " + this.name + "(" + this.periods + "课时)"); } } public class CourseFactory { private Dictionary<string,Course> courses = new Dictionary<string,Course>(); /// <summary> /// 获取课程 /// </summary> /// <param name="name"></param> /// <param name="periods"></param> /// <returns></returns> public Course GetCourse(string name, int periods) { if (!this.courses.ContainsKey(name)) //如果不存在相应的课程就新建一个课程实例 { courses.Add(name, new Course(name, periods)); } return this.courses[name]; } /// <summary> /// 获取开课总数 /// </summary> /// <returns></returns> public int GetCourseCount() { Console.WriteLine("开课总数:" + this.courses.Count); return this.courses.Count; } }
享元模式和单例模式的区别:
享元是对象级别的, 即多个相同的对象在共享区里只保存一个对象;
单例是类级别的, 即该类只能实例化出来一个对象。