1、简述
享元模式(Flyweight Pattern)是一种结构型设计模式,旨在通过共享对象来减少内存的使用和对象的创建,从而提高程序的性能。
设计模式样例:https://gitee.com/lhdxhl/design-pattern-example.git
2、什么是享元模式
享元模式通过共享对象来支持大量细粒度对象的复用,避免对象的大量创建。它通过将可共享的状态外部化,把内在状态封装到享元对象中,从而让同一对象可以被多个上下文环境共享。
享元模式的优点:
- 节省内存:通过共享对象,避免创建大量相似的对象。
- 提升性能:减少对象创建和销毁的开销,优化系统性能。
- 分离状态:将对象的内在状态和外部状态分离,增强了灵活性。
3、实际案例
假设我们要实现一个绘图应用,其中有许多相同颜色和形状的图形。如果为每个图形单独创建对象,会导致内存浪费。通过享元模式,我们可以复用相同颜色的图形对象。
// 抽象享元类
public interface Shape {
void draw(String extrinsicState);
}
// 具体享元类
public class Circle implements Shape {
private String color; // 内在状态
public Circle(String color) {
this.color = color;
}
@Override
public void draw(String extrinsicState) {
System.out.println("Drawing Circle: Color = " + color + ", Extrinsic State = " + extrinsicState);
}
}
// 享元工厂类
import java.util.HashMap;
import java.util.Map;
public class ShapeFactory {
private static final Map<String, Shape> circleMap = new HashMap<>();
public static Shape getCircle(String color) {
Shape circle = circleMap.get(color);
if (circle == null) {
circle = new Circle(color);
circleMap.put(color, circle);
System.out.println("Creating new Circle of color: " + color);
}
return circle;
}
}
// 测试代码
public class FlyweightPatternDemo {
public static void main(String[] args) {
Shape circle1 = ShapeFactory.getCircle("Red");
circle1.draw("Radius = 5");
Shape circle2 = ShapeFactory.getCircle("Blue");
circle2.draw("Radius = 10");
Shape circle3 = ShapeFactory.getCircle("Red");
circle3.draw("Radius = 15");
Shape circle4 = ShapeFactory.getCircle("Blue");
circle4.draw("Radius = 20");
}
}
输出结果
Creating new Circle of color: Red
Drawing Circle: Color = Red, Extrinsic State = Radius = 5
Creating new Circle of color: Blue
Drawing Circle: Color = Blue, Extrinsic State = Radius = 10
Drawing Circle: Color = Red, Extrinsic State = Radius = 15
Drawing Circle: Color = Blue, Extrinsic State = Radius = 20
4、应用场景
- 文本编辑器:在文本编辑器中,字符对象可以被共享,相同的字符只需创建一个对象。
- 游戏开发:例如子弹、敌人模型等可以使用享元模式来复用相同的对象。
- 数据库连接池:数据库连接池复用了相同的数据库连接。
- 缓存系统:共享缓存对象来减少内存使用。
实际案例:文本编辑器
在文本编辑器中,每个字符的格式(字体、大小、颜色等)可能是相同的,而字符本身的内容是不同的。通过享元模式,我们可以复用格式对象。
// 抽象享元类
public interface Font {
void apply(String content);
}
// 具体享元类
public class FontImpl implements Font {
private String fontName;
private int fontSize;
public FontImpl(String fontName, int fontSize) {
this.fontName = fontName;
this.fontSize = fontSize;
}
@Override
public void apply(String content) {
System.out.println("Applying Font: Name = " + fontName + ", Size = " + fontSize + ", Content = " + content);
}
}
// 享元工厂类
import java.util.HashMap;
import java.util.Map;
public class FontFactory {
private static final Map<String, Font> fontMap = new HashMap<>();
public static Font getFont(String fontName, int fontSize) {
String key = fontName + fontSize;
Font font = fontMap.get(key);
if (font == null) {
font = new FontImpl(fontName, fontSize);
fontMap.put(key, font);
System.out.println("Creating new Font: " + key);
}
return font;
}
}
// 测试代码
public class TextEditorDemo {
public static void main(String[] args) {
Font font1 = FontFactory.getFont("Arial", 12);
font1.apply("Hello");
Font font2 = FontFactory.getFont("Arial", 12);
font2.apply("World");
Font font3 = FontFactory.getFont("Times New Roman", 14);
font3.apply("Flyweight Pattern");
}
}
输出结果
Creating new Font: Arial12
Applying Font: Name = Arial, Size = 12, Content = Hello
Applying Font: Name = Arial, Size = 12, Content = World
Creating new Font: Times New Roman14
Applying Font: Name = Times New Roman, Size = 14, Content = Flyweight Pattern
5、总结
享元模式通过共享对象的方式,显著减少了系统中对象的数量,提高了内存的利用率。在实际开发中,尤其是需要创建大量相似对象的场景,享元模式是一种有效的优化策略。
评论区