Java 与设计模式(12):享元模式

这篇具有很好参考价值的文章主要介绍了Java 与设计模式(12):享元模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、定义

享元模式是一种结构型设计模式,旨在有效地共享对象以减少内存使用和提高性能。该模式的核心思想是通过共享尽可能多的相似对象来减少内存占用。它将对象分为可共享的内部状态和不可共享的外部状态。内部状态是对象的固有属性,可以在多个对象之间共享,而外部状态是对象的上下文相关属性,每个对象都是独立的。

通过共享内部状态,享元模式可以减少创建相似对象的数量,从而节省内存空间。当需要创建新对象时,可以首先检查是否已经存在具有相同内部状态的对象,如果存在,则可以直接返回共享的对象,而不是创建新的对象。这种共享对象的方式可以在大规模使用相似对象的场景中提高性能和效率。

需要注意的是,享元模式需要维护一个对象池或缓存来存储共享的对象,以便在需要时进行检索。同时,外部状态的管理也需要谨慎处理,确保每个对象在不同的上下文中都能正确地使用。

享元模式通过共享相似对象的内部状态来减少内存占用和提高性能,是一种常用的优化技术。

二、Java示例

import java.util.HashMap;
import java.util.Map;

// 具体享元类
class ConcreteFlyweight {
    private String intrinsicState;

    public ConcreteFlyweight(String intrinsicState) {
        this.intrinsicState = intrinsicState;
    }

    public void operation(String extrinsicState) {
        System.out.println("Intrinsic State: " + intrinsicState);
        System.out.println("Extrinsic State: " + extrinsicState);
    }
}

// 享元工厂类
class FlyweightFactory {
    private Map<String, ConcreteFlyweight> flyweights = new HashMap<>();

    public ConcreteFlyweight getFlyweight(String key) {
        if (flyweights.containsKey(key)) {
            return flyweights.get(key);
        } else {
            ConcreteFlyweight flyweight = new ConcreteFlyweight(key);
            flyweights.put(key, flyweight);
            return flyweight;
        }
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        FlyweightFactory factory = new FlyweightFactory();

        ConcreteFlyweight flyweight1 = factory.getFlyweight("shared");
        flyweight1.operation("state 1");

        ConcreteFlyweight flyweight2 = factory.getFlyweight("shared");
        flyweight2.operation("state 2");

        ConcreteFlyweight flyweight3 = factory.getFlyweight("unique");
        flyweight3.operation("state 3");
    }
}

在上述示例中,ConcreteFlyweight类表示具体的享元对象,包含一个内部状态intrinsicStateFlyweightFactory类作为享元工厂,维护一个对象池flyweights,用于存储共享的享元对象。

客户端代码通过FlyweightFactory获取享元对象,并调用其operation方法进行操作。当请求的享元对象已存在于对象池中时,直接返回共享的对象;否则,创建新的享元对象并添加到对象池中。

这样,通过共享相似对象的内部状态,可以减少创建对象的数量,节省内存空间。在示例中,flyweight1flyweight2共享了相同的内部状态,而flyweight3是一个独立的对象。

三、优点

享元模式的优点包括:

  1. 减少内存占用:通过共享相似对象的内部状态,可以减少创建对象的数量,从而减少内存占用。

  2. 提高性能:由于减少了对象的数量,可以减少对象的创建和销毁过程,从而提高程序的性能。

  3. 提高对象复用性:通过共享对象,可以在不同的上下文中复用对象,避免重复创建相似的对象。

  4. 简化对象管理:享元模式将对象的内部状态和外部状态进行分离,使得对象的管理更加简单和清晰。

  5. 支持大规模对象共享:当系统中存在大量相似对象时,通过享元模式可以有效地管理和共享这些对象,提高系统的可扩展性和可维护性。

享元模式通过共享相似对象的内部状态,可以减少内存占用、提高性能和对象复用性,简化对象管理,并支持大规模对象共享。这使得享元模式成为一种有价值的优化技术。

四、缺点

享元模式的缺点包括:

  1. 对象共享可能导致线程安全问题:如果多个线程同时访问共享对象,并且修改了对象的外部状态,可能会导致线程安全问题。需要在使用享元对象时进行适当的同步控制。

  2. 对象池管理增加复杂性:享元模式需要维护一个对象池或缓存来存储共享对象,这增加了对象管理的复杂性。需要确保正确地管理对象的创建、共享和销毁,避免资源泄露或过度消耗。

  3. 对象共享可能降低系统灵活性:当对象的内部状态和外部状态耦合较高时,共享对象可能限制了系统的灵活性。如果需要修改共享对象的内部状态,可能会影响到其他共享该对象的地方。

  4. 需要额外的内部状态管理:享元模式将对象的内部状态和外部状态进行分离,需要额外的管理和维护内部状态的机制。这增加了一定的复杂性和开销。

享元模式在提高性能和减少内存占用方面有优势,但也需要考虑线程安全、对象管理复杂性以及灵活性等方面的问题。在使用时需要根据具体场景进行权衡和设计。

五、使用场景

享元模式适用于以下场景:

  1. 对象数量庞大且相似:当系统中存在大量相似的对象,并且这些对象可以共享部分或全部内部状态时,可以使用享元模式来减少对象的数量和内存占用。

  2. 对象的外部状态可分离:对象的外部状态可以被分离出来,并且可以通过参数传递给对象的方法。这样可以将对象的内部状态与外部状态分离,使得对象可以共享内部状态。

  3. 需要缓存或池化对象:如果需要频繁地创建和销毁对象,并且对象的创建和销毁过程较为耗时,可以使用享元模式来缓存或池化对象,提高性能。

  4. 系统需要支持大规模对象共享:当系统中存在大量相似对象,并且这些对象需要在不同的上下文中共享时,可以使用享元模式来管理和共享这些对象,提高系统的可扩展性和可维护性。

需要注意的是,使用享元模式需要权衡对象共享带来的线程安全问题、对象管理的复杂性以及灵活性的影响。在具体应用时,需要根据实际情况进行设计和优化。

六、注意事项

在使用享元模式时,需要注意以下几点:

  1. 线程安全性:如果多个线程同时访问共享对象,并且修改了对象的外部状态,可能会导致线程安全问题。需要在使用享元对象时进行适当的同步控制,确保线程安全。

  2. 对象池管理:享元模式需要维护一个对象池或缓存来存储共享对象,需要确保正确地管理对象的创建、共享和销毁。需要注意避免资源泄露或过度消耗。

  3. 内部状态和外部状态的划分:需要合理划分对象的内部状态和外部状态,确保内部状态可以共享,而外部状态可以通过参数传递给对象的方法。同时,需要注意内部状态和外部状态的耦合度,避免影响系统的灵活性。

  4. 对象的可变性:享元模式适用于对象的内部状态是不可变的情况。如果对象的内部状态是可变的,需要考虑如何处理共享对象的可变性,以及如何保证共享对象的一致性。

  5. 性能权衡:使用享元模式可以提高性能和减少内存占用,但也需要权衡对象共享带来的管理复杂性和灵活性的影响。在具体应用时,需要根据实际情况进行设计和优化。

使用享元模式需要综合考虑线程安全性、对象管理、内部状态和外部状态的划分、对象的可变性以及性能权衡等方面的问题。在具体应用时,需要根据实际需求和场景进行适当的设计和调整。

七、在spring 中的应用

在Spring源码中,享元模式被广泛应用于各个模块和组件中,以提高性能和减少内存占用。以下是一些Spring源码中使用享元模式的示例:

  1. Bean对象的管理:在Spring的IoC容器中,Bean对象被视为享元对象。当容器启动时,会预先创建并缓存Bean对象,以便在需要时进行共享和复用。这样可以减少对象的创建和销毁开销,提高性能。

  2. 数据库连接池:Spring的JDBC模块中,使用享元模式管理数据库连接。连接池中的连接对象被视为享元对象,可以在多个线程之间共享和复用,避免频繁地创建和销毁连接,提高数据库操作的性能。

  3. 缓存管理:Spring的缓存模块中,使用享元模式管理缓存对象。缓存对象被视为享元对象,可以在多个请求之间共享和复用,避免重复计算和查询,提高系统的响应速度。

  4. 国际化资源管理:Spring的国际化模块中,使用享元模式管理国际化资源对象。国际化资源对象被视为享元对象,可以在多个地方共享和复用,避免重复加载和解析资源文件,提高国际化功能的性能。

需要注意的是,Spring框架中对享元模式的应用往往是隐式的,封装在各个模块和组件中,不会直接暴露给开发者。这样可以提供更加简洁和易用的API,同时隐藏了底层的实现细节。文章来源地址https://www.toymoban.com/news/detail-663931.html

到了这里,关于Java 与设计模式(12):享元模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • AI Chat 设计模式:12. 享元模式

    本文是该系列的第十二篇,采用问答式的方式展开,问题由我提出,答案由 Chat AI 作出,灰色背景的文字则主要是我的一些思考和补充。 享元模式是一种软件设计模式,用于 提高系统的性能和内存利用率 。该模式 通过共享对象来减少内存消耗 ,特别是在大量对象需要同时

    2024年02月14日
    浏览(29)
  • Java设计模式之结构型-享元模式(UML类图+案例分析)

    目录 一、基本概念 二、UML类图 三、角色设计 四、案例分析 4.1、基本实现 4.2、游戏角色 五、总结 享元模式是一种结构型设计模式,主要用于减少创建大量相似对象所占用的内存,它通过共享技术来有效支持大量细粒度的对象。 角色 描述 抽象享元角色 定义出对象的外部状

    2024年02月16日
    浏览(39)
  • 【设计模式——学习笔记】23种设计模式——享元模式Flyweight(原理讲解+应用场景介绍+案例介绍+Java代码实现)

    你的公司主要做一些小型的外包项目,之前给客户A做一个产品展示网站,客户A的朋友感觉效果不错,也希望做这样的产品展示网站,但是要求有些不同 有客户要求以新闻的形式发布 有客户要求以博客的形式发布 有客户要求以微信公众号的形式发布 【 传统方式】 直接复制

    2024年02月15日
    浏览(35)
  • 【Java面试题】设计模式之七种结构性模式——代理模式、适配器模式、桥接模式、装饰模式、外观模式、享元模式、组合模式

    目录 一、代理模式 二、适配器模式 三、桥接模式 四、装饰模式 五、外观模式 六、享元模式 七、组合模式 概念: 代理模式是为其他对象提供一种以代理控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对

    2023年04月09日
    浏览(41)
  • 【享元设计模式详解】C/Java/JS/Go/Python/TS不同语言实现

    享元模式(Flyweight Pattern),是一种结构型设计模式。主要用于减少创建对象的数量,以减少内存占用和提高性能。它摒弃了在每个对象中保存所有数据的方式,通过共享多个对象所共有的相同状态,让你能在有限的内存容量中载入更多对象。 当程序需要生成数量巨大的相似

    2023年04月10日
    浏览(30)
  • 设计模式——享元模式

    享元模式(Flyweight Pattern)是池技术的重要实现方式。 使用共享对象可以有效地支持大量的细粒度对象。 优点 可以大大减少应用程序创建对象的数量,降低程序内存占用。 缺点 提高了系统的复杂度,需要分离出享元对象的外部状态(key)和内部状态(对象属性),并且外部

    2024年02月16日
    浏览(29)
  • 设计模式-享元模式

    享元模式(Flyweight Pattern)是一种结构型设计模式,主要用于减少创建大量相似对象对内存资源的消耗,通过共享这些对象来提高程序性能和系统资源利用率。在实际应用场景中string就是使用了享元模式,string a = “123”; string b = “123”; 我们假设有一个场景是需要创建大量的

    2024年01月24日
    浏览(32)
  • 设计模式:享元模式

    首先我们需要简单了解一下什么是享元模式。 享元模式(Flyweight Pattern) :主要用于减少创建对象的数量,以减少内存占用和提高性能。享元模式的重点就在这个享字,通过一些共享技术来减少对象的创建,实际上Java中String值的存储,Volley中的 ByteArrayPool 也使用到了享元模式,

    2024年02月08日
    浏览(33)
  • 设计模式(22)享元模式

    一、介绍: 1、定义:享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。 2、组成结构: (1)Flyweight(抽象享元类):通常是一个接口或

    2024年02月07日
    浏览(31)
  • 设计模式之享元模式

    本文看下一种结构型设计模式,享元模式。 当程序需要大量的重复对象,并且这些大量的重复对象只有部分属性不相同,其他都是相同的时候,就可以考虑使用享元设计模式设计模式来实现。典型的如围棋游戏中的棋子,除了颜色和位置不同外,其他都相同。射击游戏中的子

    2024年02月17日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包