享元模式/Flyweight模式/对象结构型/设计模式

flyweight 享元模式(对象结构型)

Flyweight在拳击比赛中指最轻量级,即“蝇量级”或“雨量级”,这里选择使用“享元模式”的意译,是因为这样更能反映模式的用意。享元模式是对象的结构模式。享元模式以共享的方式高效地支持大量的细粒度对象。

意图

运用共享技术有效地支持大量细粒度的对象。关键字:对象共享

动机

Flyweight模式描述了如何共享对象,降低内存消耗和运行开销。Flyweight是一个共享对象,对象有内部状态和外部状态。

内部状态存于享元中,包含独立于场景的信息;

外部状态取决于场景,非共享。

适用场景

  1. 程序适用了大量对象,并造成了很大的存储开销
  2. 对象的大多数状态都可以变为外部状态
  3. 删除外部状态后,可以用相对较少的共享对象取代原对象们

享元模式要素 享元接口+享元+享元工厂

  1. Flyweight接口,规定享元需要实现的方法,外部状态,可变部分
  2. ConcreteFlyweight,具体享元对象,为内部状态提供存储空间,实现享元接口,为外部状态提供入口
  3. FlyweightFactory,享元工厂,创建和管理具体享元角色。

简单享元模式代码

interface Flyweight{
void fly(Object externalState);
} class ConcreteFlyweight implements Flyweight{
private Object innerState=null; //内部状态存储
public ConcreteFlyweight(Object innerState){
this.innerState = innerState;
} //外部状态,改变行为
@Override
public void fly(Object externalState) {
// do sth
} } class FlyweightFactory {
private Map<Object,Flyweight> files = new HashMap<Object,Flyweight>(); public Flyweight factory(Object state){
//从工厂中取出缓存的享元,不存在则创建,并放入缓存
Flyweight fly = files.get(state);
if(fly == null){
fly = new ConcreteFlyweight(state);
files.put(state, fly);
}
return fly;
}
}

组合式的享元模式

将单独可共享的具体享元对象,进行各种组合,并提供访问接口。

interface Flyweight{
void fly(Object externalState);
} class ConcreteFlyweight implements Flyweight{
private Object innerState=null;
public ConcreteFlyweight(Object innerState){
this.innerState = innerState;
}
@Override
public void fly(Object externalState) {
// do sth
} } //组合享元,提供一组享元的组合,并提供享元接口
class CompositeConcreteFlyweight implements Flyweight{
private List<Flyweight> flyweights=new ArrayList<>(); //组合享元组,添加单享元
public void add(Flyweight flyweight){
flyweights.add(flyweight);
} //享元组,外边状态接口方法
@Override
public void fly(Object externalState) {
for (Flyweight flyweight : flyweights) {
flyweight.fly(externalState);
}
}
} //享元工厂,提供组合享元和单独享元的获取方法
class FlyweightFactory {
private Map<Object,Flyweight> files = new HashMap<Object,Flyweight>(); //获取享元组
public Flyweight factory(List<Object> compositeState){
CompositeConcreteFlyweight compositeFly = new CompositeConcreteFlyweight();
for(Object state : compositeState){
compositeFly.add(factory(state));
} return compositeFly;
} //获取单享元
public Flyweight factory(Object state){
Flyweight fly = files.get(state);
if(fly == null){
fly = new ConcreteFlyweight(state);
files.put(state, fly);
}
return fly;
}
}

经典应用

文档编辑器,每个字符,都是一个享元对象,这使得文档编辑器运行很快。

还有就是JDK中的String对象,相同的字符串,地址相当(可以用==判断),所以每个字符串都是常量,并且是享元。

参考

《设计模式》

相关博客

上一篇:SQL Server 2012 开发新功能 序列对象(Sequence)(转)


下一篇:在Mac和win7上分别安装了docker后,发现原来的vagrant都启动不了了