1. 享元模式介绍
享元(Flyweight)模式是一种结构型设计模式,用于减少内存使用量和提高性能。它通过共享对象来尽量减少内存消耗。
核心思想: 享元模式的核心思想是将对象的状态分为内部状态和外部状态。内部状态是对象可以共享的部分,不会随环境改变;而外部状态则是每个对象独有的部分,会随环境改变。通过共享内部状态来减少内存使用。
类比:想象一下在一个文字处理软件中,我们需要显示大量的字符。这些字符可能有不同的字体、大小和颜色,但很多字符本身是相同的。享元模式允许我们共享字符对象的内部状态(如字符本身),而将字体、大小和颜色作为外部状态进行处理。这样,我们就可以避免为每一个字符都创建一个新的对象。
结构
- Flyweight:定义接口,通过该接口可以接受外部状态并作用于共享的内部状态。
- ConcreteFlyweight:实现Flyweight接口。存储共享的内部状态,接受外部状态并作用于共享的内部状态。
- FlyweightFactory:管理并维护享元对象的缓存。
适用场景
- 大量相似对象的场景。
- 对象创建和销毁的开销较大,且内存占用较多。
- 需要共享对象以节省内存。
2. 代码演示
让我们通过一个具体的Java代码示例来演示如何使用享元模式在文字处理软件中共享字符对象的内部状态(字符本身),并将字体、大小和颜色作为外部状态进行处理。
Flyweight: 定义字符接口
//Glyph:定义了一个draw方法,接受外部状态参数(字体、大小和颜色)
public interface Glyph {
void draw(String font, int size, String color);
}
ConcreteFlyweight: 实现共享字符
//GlyphCharacter:实现Glyph接口,存储了共享的内部状态(字符本身)。draw方法使用外部状态进行绘制
public class GlyphCharacter implements Glyph {
// 内部状态: 字符本身
private final char intrinsicChar;
public GlyphCharacter(char intrinsicChar) {
this.intrinsicChar = intrinsicChar;
}
@Override
public void draw(String font, int size, String color) {
// 外部状态: 字体、大小和颜色
System.out.println(
"Drawing character '" + intrinsicChar + "' with font: " + font + ", size: " + size + ", color: " + color);
}
}
FlyweightFactory: 管理共享字符对象的缓存
//GlyphFactory类:负责管理共享字符对象的缓存,通过getGlyph方法返回共享的字符对象。
public class GlyphFactory {
private final Map<Character, Glyph> glyphs = new HashMap<>();
public Glyph getGlyph(char intrinsicChar) {
glyphs.computeIfAbsent(intrinsicChar, GlyphCharacter::new);
return glyphs.get(intrinsicChar);
}
}
客户端代码:
//TextEditorDemo类:演示了如何使用享元模式共享字符对象,并通过外部状态绘制字符。
public class TextEditorDemo {
public static void main(String[] args) {
GlyphFactory factory = new GlyphFactory();
// 获取共享字符对象
Glyph glyphA1 = factory.getGlyph('A');
Glyph glyphA2 = factory.getGlyph('A'); // 共享同一个'A'对象
Glyph glyphB = factory.getGlyph('B');
// 使用外部状态绘制字符
glyphA1.draw("Arial", 12, "Red");
glyphA2.draw("Times New Roman", 14, "Blue");
glyphB.draw("Verdana", 16, "Green");
}
}
对应的类关系图: