定义
运用共享技术有效地支持大量细粒度对象的复用。
举例
有一个文本字符串里面存在很多重复字符,如果每个字符都用单独的对象来表示,则会占用大量的内存空间。那么使用享元模式,将相同的字符对象指向同一个实例,不同的字符创建不同的对象
结构
实现
//Flyweight类,它是所有具体享元类的超类或接口,通过这个接口,Flyweight可以接受并作用于外部状态。
abstract class Flyweight
{
public abstract void Operation(int extrinsicstate);
}
//ConcreteFlyweight是继承Flyweight超类或实现 Flyweight接口,并为内部状态增加存储空间。
class ConcreteFlyweight : Flyweight
{
public override void Operation(int extrinsicstate)
{
Console.WriteLine("具体Flyweight: " + extrinsicstate);
}
}
//UnsharedConcreteFlyweight 是指那些不需要共享的Flyweight子类。因为 Flyweight 接口共享成为可能,但它并不强制共享。
class UnsharedConcreteFlyweight : Flyweight
{
public override void Operation(int extrinsicstate)
{
Console.WriteLine("不共享的具体Flyweight:" + extrinsicstate);
}
}
//FlyweightFactory,是一个享元工厂,用来创建并管理 Flyweight对象。
//它主要是用来确保合理地共享Flyweight,当用户请求一个Flyweight时,FlyweightFactory对象提供一个已创建的实例或者创建一个(如果不存在的话)。
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]);
}
}
class Program
{
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);
}
}
优点
- (1)享元模式可以减少内存中对象的数量,使得相同或者相似的对象在内存中只保存一份,从而可以节约系统资源,提高系统性能。
- (2)在享元模式中,外部状态相对独立,而且不会影响其内部状态,从而使得享元对象可以在不同的环境中被共享。
缺点
- (1)享元模式使得系统变得复杂,需要分离出内部状态和外部状态,这使得程序的逻辑复杂化。
- (2)为了使对象可以共享,享元模式需要将享元对象的部分状态外部化,而读取外部状态将使得运行时间变长。
适用环境
- (1)一个系统有大量相同或者相似的对象,造成了内存的大量耗费。
- (2)对象的大部分状态都可以外部化,可以将这些外部状态传入对象中。
- (3)在使用享元模式时需要维护一个存储享元对象的享元池,而这需要耗费一定的系统资源,因此,在需要多次重复使用享元对象时才值得使用享元模式。