基本了解:
享元模式(Flyweight):运用共享技术有效地支持大量细粒度的对象。来提供应用程序的性能,节省系统中重复创建对象实例的性能消耗。可以包含以下两点含义:1、当我们系统中某个对象类型的实例较多的情况。2、并且要求这些实例进行分类后,发现真正有区别的分类很少的情况。享元模式的基本结构图。
内部状态与外部状态
在享元对象内部并且不会随环境改变而改变的共享部分,可以称为享元对象的内部状态,而随环境改变而改变的、不可共享的状态就是外部状态。享元模式可以避免大量非常相似类的开销。享元模式Flyweight执行所需的状态时有内部的也可能有外部的。内部状态存储于ConcreteFlyweight对象中,而外部对象则应该考虑有客户端对象存储或计算,当调用Flyweight对象的操作时,将该状态传递给他。结合网站开发的例子。
//用户,用于网站的客户账号,是网站类的外部状态
public class User
{
private string name;
public User(string name)
{
this.name = name;
}
public string Name
{
get { return name; }
}
}
//网站抽象类
abstract class WebSite
{
public abstract void Use(User user);//使用 方法需要传递 用户 对象
}
//具体网站类
class ConcreteWebSite:WebSite
{
private string name = "";
public ConcreteWebSite(string name)
{
this.name = name;
}
public override void Use(User user) //实现use方法
{
Console.WriteLine("网站分类:" + name + "用户:" + user.Name);
}
}
//网站工厂类
//网站工厂
class WebSiteFactory
{
private Hashtable flyweights = new Hashtable();
//获得网站分类
public WebSite GetWebSiteCategory(string key) //判断是否存在这个对象,如果存在,则直接返回,若不存在,则实例化它再返回
{
if (!flyweights.ContainsKey(key))
flyweights.Add(key, new ConcreteWebSite(key));
return ((WebSite)flyweights[key]);
}
//获得网站分类总数
public int GetWebSiteCount() //得到实例的个数
{
return flyweights.Count;
}
}
客户端代码:
static void Main(string[] args)
{
WebSiteFactory f = new WebSiteFactory();
WebSite fx = f.GetWebSiteCategory("产品展示"); //实例化“产品展示”的“网站”对象
fx.Use(new User("小菜"));
WebSite fy = f.GetWebSiteCategory("产品展示"); //共享上方生成的对象,不再实例化
fy.Use(new User("大鸟"));
WebSite fz = f.GetWebSiteCategory("产品展示");
fz.Use(new User("娇娇"));
WebSite f1 = f.GetWebSiteCategory("博客");
f1.Use(new User("老顽童"));
WebSite f2 = f.GetWebSiteCategory("博客");
f2.Use(new User("桃谷六仙"));
WebSite f3 = f.GetWebSiteCategory("博客");
f3.Use(new User("南海鳄神"));
Console.WriteLine("得到网站分类总数为{0}", f.GetWebSiteCount()); //统计实例化个数,结果输出显示
Console.Read();
}
享元模式应用
1、应用程序使用了大量的对象,而大量的这些对象造成了很大的存储开销是考虑使用。
2、对象的大多数状态为外部状态,删除这些状态可以用相对较少的共享对象取代。
因为用了享元模式,有了共享的对象,实例总数就大大减少了,如果共享的对象越多,存储节约就越多,节约量随着共享状态的增多而增大。