定义:运用共享技术有效地支持大量细粒度的对象。 系统只使用少量的对象,而这些对象都很近,状态变化很小,对象使用次数增多。
享元模式包含如下角色:
Flyweight(抽象享元类 ):是所有的具体享元类的基类,为这些类规定出需要实现的公共接口。那些需要外部状态的操作可以通过调用方法以参数形式传入。
ConcreteFlyweight(具体享元类 ):实现抽象享元角色所规定的接口。如果有内部状态的话,可以在类内部定义。
UnsharedConcreteFlyweight(非共享具体享元类 ):不会被共享的具体享元类,这些类不需要实现共享接口,通常只在客户端直接调用时使用。
FlyweightFactory(享元工厂类):用于创建和使用存储在享元池中的享元对象,若请求对象已存在,就返回这个享元对象,否则就创建一个新的享元对象,并将其存储在享元工厂类中以备后续使用。
举例
创建具体享元A、B,通过非共享享元调用
- 抽象享元类
public interface Flyweight
{
void Operation(UnsharedConcreteFlyweight state);
}
- 具体享元类
public class ConcreteFlyweight : Flyweight
{
private String key;
public ConcreteFlyweight(String key)
{
this.key = key;
Console.WriteLine("具体享元" + key + "被创建!");
}
public void Operation(UnsharedConcreteFlyweight outState)
{
Console.WriteLine("具体享元" + key + "被调用,");
Console.WriteLine("非享元信息是:" + outState.Info);
}
}
- 非共享具体享元类
public class UnsharedConcreteFlyweight
{
private String info;
public UnsharedConcreteFlyweight(String info)
{
this.Info = info;
}public string Info { get => info; set => info = value; }
}
- 享元工厂类
class FlyweightFactory
{
private Hashtable flyweights = new Hashtable();
public Flyweight getFlyweight(String key)
{
Flyweight flyweight = (Flyweight)flyweights[key];
if (flyweight != null)
{
Console.WriteLine("具体享元" + key + "已存在!");
}
else
{
flyweight = new ConcreteFlyweight(key);
flyweights.Add(key, flyweight);
}
return flyweight;
}
}
- 客户类
class Program
{
static void Main(string[] args)
{
FlyweightFactory factory = new FlyweightFactory();
Flyweight Test_1 = factory.getFlyweight("A");
Flyweight Test_2 = factory.getFlyweight("A");
Flyweight Test_3 = factory.getFlyweight("B");
Test_1.Operation(new UnsharedConcreteFlyweight("第1次调用A。"));
Test_2.Operation(new UnsharedConcreteFlyweight("第2次调用A。"));
Test_3.Operation(new UnsharedConcreteFlyweight("第1次调用B。"));
}
}
总结:抽象享元类中定义具体享元类需要实现的方法,具体享元类中还可添加自己的属性和方法,非共享享元类不需实现抽象享元类可直接调用,客户通过享元工厂创建具体享元类时首先会检查工厂内是否存在该对象,存在则直接返回该对象,不存在则创建该对象并存入工厂。