侧边栏壁纸
博主头像
拾荒的小海螺博主等级

只有想不到的,没有做不到的

  • 累计撰写 224 篇文章
  • 累计创建 19 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

JAVA:享元模式(Flyweight Pattern)的技术指南

拾荒的小海螺
2025-03-31 / 0 评论 / 0 点赞 / 14 阅读 / 5956 字

1、简述

享元模式(Flyweight Pattern)是一种结构型设计模式,旨在通过共享对象来减少内存的使用和对象的创建,从而提高程序的性能。

设计模式样例:https://gitee.com/lhdxhl/design-pattern-example.git

1743412119998.jpg


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、总结

享元模式通过共享对象的方式,显著减少了系统中对象的数量,提高了内存的利用率。在实际开发中,尤其是需要创建大量相似对象的场景,享元模式是一种有效的优化策略。

0

评论区