享元模式

来源:互联网 发布:淘宝充话费赚钱吗 编辑:程序博客网 时间:2024/06/06 17:38

享元模式 


享元模式(英语:Flyweight Pattern)是一种软件设计模式。它使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件;它适合用于当大量物件只是重复因而导致无法令人接受的使用大量内存。通常物件中的部分状态是可以分享。常见做法是把它们放在外部数据结构,当需要使用时再将它们传递给享元。

  • 中文名称

    享元模式

  • 外文名称

    Flyweight Pattern

 
  • 类别

    设计模式

目录
1定义
2结构
3使用场景
4示例


定义

享元模式(FlyWeight),运用共享技术有效的支持大量细粒度的对象。

折叠结构

折叠两个状态

内蕴状态存储在享元内部,不会随环境的改变而有所不同,是可以共享的

外蕴状态是不可以共享的,它随环境的改变而改变的,因此外蕴状态是由客户端来保持(因为环境的变化是由客户端引起的)。

折叠UML结构图

(1) 抽象享元角色:为具体享元角色规定了必须实现的方法,而外蕴状态就是以参数的形式通过此方法传入。在Java中可以由抽象类、接口来担当。

(2) 具体享元角色:实现抽象角色规定的方法。如果存在内蕴状态,就负责为内蕴状态提供存储空间。

(3) 享元工厂角色:负责创建和管理享元角色。要想达到共享的目的,这个角色的实现是关键!

(4) 客户端角色:维护对所有享元对象的引用,而且还需要存储对应的外蕴状态

折叠使用场景


如果一个应用程序使用了大量的对象,而这些对象造成了很大的存储开销的时候就可以考虑是否可以使用享元模式。

例如,如果发现某个对象的生成了大量细粒度的实例,并且这些实例除了几个参数外基本是相同的,如果把那些共享参数移到类外面,在方法调用时将他们传递进来,就可以通过共享大幅度单个实例的数目。

折叠示例

典型的享元模式的例子为文书处理器中以图形结构来表示字符。一个做法是,每个字形有其字型外观, 字模 metrics, 和其它格式资讯,但这会使每个字符就耗用上千字节。取而代之的是,每个字符参照到一个共享字形物件,此物件会被其它有共同特质的字符所分享;只有每个字符(文件中或页面中)的位置才需要另外储存。以下程式用来解释上述的文件例子。这个例子用来解释享元模式利用只载立执行立即小任务所必需的资料,因而减少内存使用量。

public enum FontEffect {

BOLD, ITALIC, SUPERSCRIPT, SUBSCRIPT, STRIKETHROUGH

}

public final class FontData {

/**

* A weak hash map will drop unused references to FontData.

* Values have to be wrapped in WeakReferences,

* because value objects in weak hash map are held by strong references. *

/

private static final WeakHashMap<FontData, WeakReference<FontData>> FLY_WEIGHT_DATA = newWeakHashMap<FontData, WeakReference<FontData>>();

private final int pointSize;

private final String fontFace;

private final Color color;

private final Set<FontEffect> effects;

private FontData(int pointSize, String fontFace, Color color, EnumSet<FontEffect> effects){ this.pointSize = pointSize;

this.fontFace = fontFace;

this.color = color;

this.effects = Collections.unmodifiableSet(effects);

}

public static FontData create(int pointSize, String fontFace, Color color, FontEffect... effects) { EnumSet<FontEffect> effectsSet = EnumSet.noneOf(FontEffect.class);

for (FontEffect fontEffect : effects) {

effectsSet.add(fontEffect);

}

// We are unconcerned with object creation cost, we are reducing overall memory consumption FontData data = newFontData(pointSize, fontFace, color, effectsSet);

// Retrieve previously created instance with the given values if it (still) exists WeakReference<FontData> ref = FLY_WEIGHT_DATA.get(data);

FontData result = (ref != null) ? ref.get() : null// Store new font data instance if no matching instance exists

if (result == null) {

FLY_WEIGHT_DATA.put(data, new WeakReference<FontData> (data));

result = data;

}

// return the single immutable copy with the given values

return result;

}

@Override

public boolean equals(Object obj) {

if (obj instanceof FontData) {

if (obj == this) {

return true;

}

FontData other = (FontData) obj;

return other.pointSize == pointSize && other.fontFace.equals(fontFace) && other.color.equals(color) && other.effects.equals(effects);

}

return false;

}

@Override

public int hashCode() {

return (pointSize * 37 + effects.hashCode() * 13) * fontFace.hashCode();

}

// Getters for the font data, but no setters. FontData is immutable.

}

0 0
原创粉丝点击