享元模式:是结构型模式中的一种.
享元模式英文称为”Flyweight Pattern”,我非常感谢将Flyweight Pattern翻译成享元模式的那位强人,因为这个词将这个模式使用的方式明白得表示了出来,如果翻译成为雨量级模式或者蝇量级模式等等,
虽然可以含蓄的便显出使用此模式达到的目的,但是还是没有抓住此模式的关键。
享元模式广义上的定义为:采用一个共享来避免大量拥有相同内容对象的开销。这种开销中最常见,直观的就是内存的损耗,享元模式以共享的方式高效的支持大量的细粒度对象。
使用享元模式有两个优点,一个是节省内存,另外一个就是可以统一维护享元模式和对象池比较相似。
不同点:享元模式中一个对象可以被多个对象引用。
而对象池中一个对象只能被一个对象引用。
很多书面上的享元模式都有两个概念:外部状态
和内部状态。这个说的和上面的意思是一样的。
具体的定义为:
1.内部状态:在享元对象的内部并且不会随着环境的改变而改变的共享部分。
2.外部状态:随环境改变而改变的,不可以共享的状态。
目录
1. 意图:
减少创建对象的数量,以减少内存占用和提高性能。
定义:运用共享技术有效地支持大量细粒度的对象。
2. 如何使用:
如何解决:将对象划分内部状态和外部状态。将对象的内部状态用唯一标识码判断,如果内存有,则返回这个唯一标识码所标示的对象。
优点:大大减少对象的创建,降低系统的内存,使效率提高。
缺点:提高了系统的复杂度,需要分离出外部状态和内部状态,而且外部状态具有固有化的性质,不应该随着内部状态的变化而变化,否则会造成系统的混乱。
何时使用:
1.系统中有大量相似对象。
2.需要缓冲池的场景。
注意事项:1.注意划分外部状态和内部状态,否则可能会引起线程安全问题。
2.这些类必须有一个工厂对象加以控制。
3. UML模板:
4. 关键代码:
public class FlyweightMode : MonoBehaviour
{
void Start()
{
int extrinsicstate = 22;
FlyweightFactory f = new FlyweightFactory();
Flyweight fx = f.GetFlyweight("X");
fx.Operation(--extrinsicstate);
Flyweight fy = f.GetFlyweight("Y");
fy.Operation(--extrinsicstate);
Flyweight fz = f.GetFlyweight("Z");
fz.Operation(--extrinsicstate);
UnsharedConcreteFlyweight uf = new UnsharedConcreteFlyweight();
uf.Operation(--extrinsicstate);
}
}
//所有具体享元类的超类或接口,通过这个接口,Flyweight可以接受并作用于外部状态。
public abstract class Flyweight
{
public abstract void Operation(int extrinsicstate);
}
//继承Flyweight超类或实现Flyweight接口,并为内部状态增加存储空间
public class ConcreteFlyweight : Flyweight
{
public override void Operation(int extrinsicstate)
{
Debug.Log("具体Flyweight:"+extrinsicstate);
}
}
//指那些不需要共享的Flyweight子类,因为Flyweight接口共享成为可能,但它并不强制共享。
public class UnsharedConcreteFlyweight : Flyweight
{
public override void Operation(int extrinsicstate)
{
Debug.Log("不共享的具体Flyweight:"+extrinsicstate);
}
}
//一个享元工厂,用来创建并管理Flyweight对象,它主要用来确保合理地共享Flyweight,
//当用户请求一个Flyweight时,FlyweightFactory对象提供一个已创建的实例或者创建一个(如果不存在的话)
public class FlyweightFactory
{
private Hashtable flyweights = new Hashtable();
public FlyweightFactory()
{
flyweights.Add("X",new ConcreteFlyweight());
flyweights.Add("Y",new ConcreteFlyweight());
flyweights.Add("Z",new ConcreteFlyweight());
}
public Flyweight GetFlyweight(string key)
{
return ((Flyweight)flyweights[key]);
}
}
5. 实例:
UML图:
代码:
public class FlyweightModeDemo:MonoBehaviour
{
private void Start()
{
WebSiteFactory f = new WebSiteFactory();
WebSite fx = f.GetWebSiteCategory("产品展示");
fx.Use(new User("小菜"));
WebSite fy = f.GetWebSiteCategory("产品展示");
fx.Use(new User("大鸟"));
WebSite fz = f.GetWebSiteCategory("产品展示");
fz.Use(new User("娇娇"));
WebSite f1 = f.GetWebSiteCategory("博客");
f1.Use(new User("老顽童"));
WebSite fm = f.GetWebSiteCategory("博客");
fm.Use(new User("桃谷六仙"));
WebSite fn = f.GetWebSiteCategory("博客");
fn.Use(new User("南海鳄神"));
Debug.LogFormat("网站分类总数为{0}",f.GetWebSiteCount());
}
}
//用户
public class User
{
private string name;
public User(string name)
{
this.name = name;
}
public string Name
{
get { return name; }
}
}
public abstract class WebSite
{
public abstract void Use(User user);
}
//具体网址类
public class ConcreteWebSite : WebSite
{
private string name = "";
public ConcreteWebSite(string name)
{
this.name = name;
}
public override void Use(User user)
{
Debug.Log("网站分类:"+name+"用户:"+user.Name);
}
}
//网站工厂类
public 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;
}
}