结构型设计模式——享元模式

享元模式是一种结构型设计模式,用于通过共享相似对象的内部状态来减少内存消耗。在内存有限的情况下,享元模式通过享元工厂管理享元对象的缓存,提供相同内在状态的对象复用。这种模式常用于需要大量细粒度对象的场景,如Java中的Integer.valueOf()等方法。享元类包含内在状态,而外在状态由客户端管理。享元模式与单例模式的区别在于,享元可以有多个实例,且享元对象是不可变的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

摘要

享元模式(Flyweight Pattern): 利用共享的方式来支持大量细粒度的对象,这些对象一部分内部状态是相同的。 它让某个类的一个实例能用来提供许多"虚拟实例"。

一、享元设计模式意图

享元模式 (Flyweight) 是一种结构型设计模式,它摒弃了在每个对象中保存所有数据的方式, 通过共享多个对象所共有的相同状态, 让你能在有限的内存容量中载入更多对象。

二、享元设计模式场景

  • 仅在程序必须支持大量对象且没有足够的内存容量时使用享元模式。

三、享元设计模式类图

  1. 享元模式只是一种优化。 在应用该模式之前, 你要确定程序中存在与大量类似对象同时占用内存相关的内存消耗问题, 并且确保该问题无法使用其他更好的方式来解决。
  2. 享元 (Flyweight) 类包含原始对象中部分能在多个对象中共享的状态。 同一享元对象可在许多不同情景中使用。 享元中存储的状态被称为 “内在状态”。 传递给享元方法的状态被称为 “外在状态”。
  3. 情景 (Context) 类包含原始对象中各不相同的外在状态。 情景与享元对象组合在一起就能表示原始对象的全部状态。
  4. 通常情况下, 原始对象的行为会保留在享元类中。 因此调用享元方法必须提供部分外在状态作为参数。 但你也可将行为移动到情景类中, 然后将连入的享元作为单纯的数据对象。
  5. 客户端 (Client) 负责计算或存储享元的外在状态。 在客户端看来, 享元是一种可在运行时进行配置的模板对象, 具体的配置方式为向其方法中传入一些情景数据参数。
  6. 享元工厂 (Flyweight Factory) 会对已有享元的缓存池进行管理。 有了工厂后, 客户端就无需直接创建享元, 它们只需调用工厂并向其传递目标享元的一些内在状态即可。 工厂会根据参数在之前已创建的享元中进行查找, 如果找到满足条件的享元就将其返回; 如果没有找到就根据参数新建享元。

四、享元设计模式实现

Flyweight : 它是所有具体享元类的超类或接口,通过这个接口,Flyweight 可以接受并作用于外部状态。

abstract class Flyweight {
    public abstract void operation(int extrinsicstates);
}

ConcreteFlyweight : 是继承 Flyweight 超类或实现 Flyweight 接口,并为内部状态增加存储空间。

class ConcreteFlyweight extends Flyweight {
    @Override
    public void operation(int extrinsicstates) {
        System.out.println("共享的Flyweight : " + extrinsicstates);
    }
}

UnsharedConcreteFlyweight : 指那些不需要共享的 Flyweight 子类,因为 Flyweight 接口共享成为可能,但它并不强制共享。

class UnsharedConcreteFlyweight extends Flyweight {
    @Override
    public void operation(int extrinsicstates) {
        System.out.println("不共享的Flyweight : " + extrinsicstates);
    }
}

FlywightFactory :是一个享元工厂,用来创建并管理 Flyweight 对象。它主要是用来确保合理地共享 Flyweight ,当用户请求一个 Flyweight 时, FlyweightFactory 对象提供一个已创建的实例或创建一个(如果对象不存在的话)。

class FlywightFactory {
    private Hashtable<String, Flyweight> flyweights = new Hashtable<String, Flyweight>();

    public FlywightFactory() {
        flyweights.put("X", new ConcreteFlyweight());
        flyweights.put("Y", new ConcreteFlyweight());
        flyweights.put("Z", new ConcreteFlyweight());
    }

    public Flyweight getFlyweight(String key) {
        return ((Flyweight)flyweights.get(key));
    }
}
public class FlyweightPattern {
    public static void main(String[] args) {
        int extrinsicstates = 1;
        FlywightFactory factory = new FlywightFactory();

        Flyweight fx = factory.getFlyweight("X");
        fx.operation(extrinsicstates);

        Flyweight fy = factory.getFlyweight("Y");
        fy.operation(++extrinsicstates);

        Flyweight fz = factory.getFlyweight("Z");
        fz.operation(++extrinsicstates);

        Flyweight uf = new UnsharedConcreteFlyweight();
        uf.operation(++extrinsicstates);
    }
}

======================================================

共享的Flyweight : 1
共享的Flyweight : 2
共享的Flyweight : 3
不共享的Flyweight : 4

五、享元设计模式总结

你可以使用享元模式 (opens new window)实现组合模式 (opens new window)树的共享叶节点以节省内存。

  • 享元 (opens new window)展示了如何生成大量的小型对象, 外观模式 (opens new window)则展示了如何用一个对象来代表整个子系统。
  • 如果你能将对象的所有共享状态简化为一个享元对象, 那么享元 (opens new window)就和单例模式 (opens new window)类似了。 但这两个模式有两个根本性的不同。
  • 只会有一个单例实体, 但是享元类可以有多个实体, 各实体的内在状态也可以不同。
  • 单例对象可以是可变的。 享元对象是不可变的。

六、享元设计模式开源示例

Java 利用缓存来加速大量小对象的访问时间。

  • java.lang.Integer#valueOf(int)
  • java.lang.Boolean#valueOf(boolean)
  • java.lang.Byte#valueOf(byte)
  • java.lang.Character#valueOf(char)

博文参考

结构型 - 享元(Flyweight) | Java 全栈知识体系

设计模式之享元模式 | DESIGN

DVWA(Damn Vulnerable Web Application)是一个用于学习和练习网络安全的靶场平台,下面是DVWA的搭建过程: 1. 安装环境: - 首先,你需要将 DVWA 下载到你的 Web 服务器上。你可以在 GitHub 上找到 DVWA 的源码。 - 将下载好的源码放置在你的 Web 服务器根目录下。 2. 配置数据库: - 打开 DVWA 文件夹中的 `config` 子文件夹,将 `config.inc.php.dist` 文件重命名为 `config.inc.php`。 - 编辑 `config.inc.php` 文件,配置数据库连接信息。输入你的 MySQL 数据库主机名、用户名、密码和数据库名称,保存文件。 3. 初始化数据库: - 在浏览器中访问 DVWA 的 URL,如 `http://your-ip-address/dvwa`。 - 首次访问时,DVWA 会自动检测你的环境并引导你初始化数据库。点击 "Create / Reset Database" 按钮进行初始化。 4. 设置安全性级别: - 初始化数据库后,DVWA 会跳转到登录页面。使用默认的管理员用户名和密码(admin/password)登录。 - 在 "DVWA Security" 标签页中,选择安全性级别。初始情况下,选择 `low` 级别以方便学习和实践。 5. 开始使用 DVWA: - 确认安全性级别后,在 DVWA 主界面上你将看到各种漏洞和挑战,比如 SQL 注入、跨站点脚本(XSS)、文件包含等。 - 选择你感兴趣的漏洞或挑战,按照提示进行测试和实践。 请注意,在搭建 DVWA 靶场之前,确保你已经具备了运行 Web 服务器和 MySQL 数据库的环境,并且已经正确配置了相关的服务。此外,为了安全起见,建议在局域网或虚拟机环境中使用 DVWA 进行学习和实践。 希望以上信息能对你有所帮助!如果有任何其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

庄小焱

我将坚持分享更多知识

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

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

打赏作者

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

抵扣说明:

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

余额充值