Java设计模式之享元(Flyweight)模式

享元(Flyweight)模式通过共享对象来最小化内存使用和实例化对象的数量。

什么是享元模式

在Java应用程序中,创建和处理大量对象会占用大量的内存和处理器时间,从而影响应用程序的性能。这时候,享元模式可以派上用场了。享元模式利用对象共享来最小化对象的数量,从而提高应用程序的性能。在享元模式中,内部状态与外部状态是分开存储的,内部状态指的是同类对象间具有的相同信息,而外部状态指的是对象间的不同信息。通过共享内部状态,并将外部状态作为参数传进去,可以减少对象的创建和存储,从而节省资源。

享元模式的使用场景

适用于需要创建大量相似对象或者对象数量很大的场景,例如对象池、GUI界面中的图形和文本等。

组成部分:

  1. 抽象享元:定义享元接口方法,规定外部状态为参数。

  2. 具体享元:实现抽象享元定义的方法。

  3. 享元工厂:创建并管理享元对象,确保共享相同享元对象。

享元模式的代码示例

我们将创建一个 Text(文本)接口和一个 TextType(文本类型)类来表示我们的享元。文本类型只需指定文本应使用的字体,因为颜色是外部状态。

我们还将使用一个 Color(颜色)类来表示文本的颜色。在我们的例子中,颜色将作为外部状态传递给 TextType 对象。

首先,我们需要定义一个抽象的文本接口:

// 文本接口
public interface Text {
    void draw(String content);
}

然后,我们可以实现具体的文本和颜色类,这里我们实现了两种颜色类:

// 颜色类
public class Color {
    // 颜色名称
    private final String color;

    public Color(String color) {
        this.color = color;
    }

    public String getColor() {
        return color;
    }
}

// 具体文本类
public class TextType implements Text {
    // 字体名称
    private final String font;

    public TextType(String font) {
        this.font = font;
    }

    // 绘制文本
    @Override
    public void draw(String content) {
        System.out.println("使用 " + font + " 字体绘制文本,内容为:" + content);
    }
}

在 TextType 类中,我们使用了共享的字体对象,但外部状态是通过 draw() 方法传递进来的。

接下来,我们可以创建一个享元工厂来管理文本和颜色对象:

// 享元工厂,用于创建和管理文本共享对象
import java.util.HashMap;

public class TextFactory {
    // 存放颜色和文本类型之间的映射关系
    private static final HashMap<Color, TextType> textTypeMap = new HashMap<>();

    // 根据颜色和字体获取文本类型
    public static TextType getText(Color color, String font) {
        // 判断是否存在对应的共享文本对象
        TextType textType = textTypeMap.get(color);

        // 如果不存在,则创建一个新的共享文本对象,并加入到Map中
        if (textType == null) {
            textType = new TextType(font);
            textTypeMap.put(color, textType);
        }

        return textType;
    }
}

最后,我们可以使用 TextFactory 和 Color 对象来创建、共享和使用文本对象:

// 测试代码
public class FlyweightDemo {
    private static final String[] fonts = new String[]{"Arial", "Times New Roman", "Verdana", "Calibri"};
    private static final String[] colors = new String[]{"Red", "Green", "Blue", "Orange"};

    public static void main(String[] args) {
        for (int i = 0; i < 20; i++) {
            Color color = getColor();
            String font = getFont();
            TextType textType = TextFactory.getText(color, font);
            textType.draw("贵州欢迎您!");
        }
    }

    private static String getFont() {
        return fonts[(int) (Math.random() * fonts.length)];
    }

    private static Color getColor() {
        return new Color(colors[(int) (Math.random() * colors.length)]);
    }
}

运行结果如下:

使用 Arial 字体绘制文本,内容为:贵州欢迎您!
使用 Calibri 字体绘制文本,内容为:贵州欢迎您!
使用 Calibri 字体绘制文本,内容为:贵州欢迎您!
使用 Arial 字体绘制文本,内容为:贵州欢迎您!
使用 Times New Roman 字体绘制文本,内容为:贵州欢迎您!
使用 Arial 字体绘制文本,内容为:贵州欢迎您!
使用 Arial 字体绘制文本,内容为:贵州欢迎您!
使用 Times New Roman 字体绘制文本,内容为:贵州欢迎您!
使用 Calibri 字体绘制文本,内容为:贵州欢迎您!
使用 Verdana 字体绘制文本,内容为:贵州欢迎您!
使用 Times New Roman 字体绘制文本,内容为:贵州欢迎您!
使用 Arial 字体绘制文本,内容为:贵州欢迎您!
使用 Calibri 字体绘制文本,内容为:贵州欢迎您!
使用 Calibri 字体绘制文本,内容为:贵州欢迎您!
使用 Verdana 字体绘制文本,内容为:贵州欢迎您!
使用 Verdana 字体绘制文本,内容为:贵州欢迎您!
使用 Times New Roman 字体绘制文本,内容为:贵州欢迎您!
使用 Arial 字体绘制文本,内容为:贵州欢迎您!
使用 Times New Roman 字体绘制文本,内容为:贵州欢迎您!
使用 Verdana 字体绘制文本,内容为:贵州欢迎您!

享元模式的实际应用

享元(Flyweight)模式是一种轻量级的设计模式,在应用开发中,我们通常会使用一些常用框架来帮助我们实现享元模式。

  1. Java 缓存库

Java 缓存库,如 Ehcache、Guava Cache、Caffeine 等,为应用程序提供了跨多个会话和请求的缓存容器,以减少数据库访问和增加性能。

这些缓存库通常使用享元模式来存储和管理缓存对象,以提高应用程序性能。

  1. Servlet

Servlet API 中的 HttpSession 对象使用了享元模式来处理会话状态。服务器只需为每个新会话创建一个 HttpSession 对象,其余的会话状态可以共享。

在这种情况下,每个 HttpSession 仅包含对会话的参考,而实际的数据则存储在一个更大的共享存储区域中。

  1. Spring Framework

Spring Framework是一个轻量级的 Java 开发框架,它提供了大量的特性和功能,其中之一就是使用享元模式来管理大量的 Bean 对象。

Spring Framework 使用了很多设计模式,在 DI(Dependency Injection)和 AOP(Aspect Oriented Programming)方面,也使用了享元模式来处理 Bean 对象的创建和管理。

  1. JDBC

JDBC(Java Database Connectivity)API 用于访问关系型数据库。在 JDBC 中,数据库连接是一个昂贵的资源,因为它需要建立网络连接和进行身份验证等复杂操作。

因此,JDBC 使用了池化技术来管理数据库连接,这也是使用了享元模式的一种方式。

关注微信公众号:“小虎哥的技术博客”。我们会定期发布关于Java技术的详尽文章,让您能够深入了解该领域的各种技巧和方法,让我们一起成为更优秀的程序员👩‍💻👨‍💻!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小虎哥的技术博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值