一、名称
享元模式(Flyweight)
二、属性
结构型
三、定义
运用共享技术有效地支持大量细粒度的对象
四、白话:一个东西大家通过不同方式来分享使用
五、何时用
如果一个应用程序使用了大量的对象,而大量的这些对象造成了很大的存储开始时就应该考虑使用,还有就是对象的大多数状态可以外部状态,如果删除对象的外部状态那么可以用相对较少的共享对象取代很多组对象,此时可以考虑使用享元模式。
六、优点
大大减少对象的创建,减低系统的内存,使效率提高。
七、不足
提高了系统的复杂度,需要分离出外部状态和内部状态,而且外部状态具有固有化的性质,不应该随着内部状态的变化而变化,否则会造成系统的混乱。
补充:内部状态和外部状态
内部状态:在享元对象内部并且不会随环境改变而改变的共享部分,可以称为享元对象的内部状态
外部状态:随环境改变而改变的,不可以共享的状态就是外部状态了。(如客户的账号和密码)
享元模式执行时需要的状态有时是内部的也有可能是外部的,内部状态存储于ConcreteFlyweight对象之中,而外部对象则应该考虑有客户端对象存储或计算,当调用Flyweight对象的操作时,将该状态传递给它。
八、使用场景
1、系统中有大量相似对象
2、需要缓冲池的场景
九、注意事项
1、注意划分内部状态和外部状态,否则可能会引起线程安全问题
2、这些类必须有一个工厂对象加以控制
十、类图
十一:实例
1、
//flyweight类,它是所有具体享元类的超类或接口,通过这个接口,Flyweight可以接受并作用于外部状态
abstract class Flyweight
{
public abstract void Operation(int extrinsicstate);
}
2、
//FlyweightFactory,是一个享元工厂,用来创建并管理Flyweight对象,它主要是用来确保合理的共享Flyweight,
//当用户请求一个Flyweight时,Flyweight对象提供一个已创建的实例或者创建一个(如果不存在的话)
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]);
}
}
3、
//ConcreteFlyweight是继承Flyweight超类或实现Flyweight接口,并为内部状态增加存储空间。
class ConcreteFlyweight : Flyweight
{
public override void Operation(int extrinsicstate)
{
Console.WriteLine("具体Flyweight:" + extrinsicstate);
}
}
4、
//UnsharedConcreteFlyweight是指那些不需要共享的Flyweight子类,因为Flyweight接口共享成为可能,但它并不强制共享。
class UnsharedConcreteFlyweight : Flyweight
{
public override void Operation(int extrinsicstate)
{
Console.WriteLine("不共享的具体Flyweight:" + extrinsicstate);
}
}
5、
static void Main(string[] args)
{
//代码外部状态
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);
Console.Read();
class Program
{
internal UnsharedConcreteFlyweight UnsharedConcreteFlyweight
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}
internal ConcreteFlyweight ConcreteFlyweight
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}
internal FlyweightFactory FlyweightFactory
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}