当前位置: 首页> 游戏> 单机 > seo推广计划_汕头澄海疫情最新消息_怎么申请网站_新闻联播俄罗斯与乌克兰

seo推广计划_汕头澄海疫情最新消息_怎么申请网站_新闻联播俄罗斯与乌克兰

时间:2025/7/9 8:07:26来源:https://blog.csdn.net/flzjcsg3/article/details/145696195 浏览次数:0次
seo推广计划_汕头澄海疫情最新消息_怎么申请网站_新闻联播俄罗斯与乌克兰

👋hi,我不是一名外包公司的员工,也不会偷吃茶水间的零食,我的梦想是能写高端CRUD
🔥 2025本人正在沉淀中… 博客更新速度++
👍 欢迎点赞、收藏、关注,跟上我的更新节奏
🎵 当你的天空突然下了大雨,那是我在为你炸乌云

文章目录

  • 一、入门
    • 什么是享元模式?
    • 为什么要有享元模式?
    • 怎么实现享元模式?
  • 二、享元模式在框架源码中的运用
    • Java 中的 Integer 缓存
    • Java 中的 ThreadPoolExecutor
  • 三、总结
    • 享元模式的优点
    • 享元模式的缺点
    • 享元模式的适用场景

一、入门

什么是享元模式?

享元模式(Flyweight Pattern)是一种结构型设计模式,旨在通过共享对象来减少内存使用,特别适用于存在大量相似对象的情况。
它的核心思想是将对象的内在状态(不变的部分)与外在状态(变化的部分)分离,从而减少对象的数量。

为什么要有享元模式?

假设我们正在开发一个在线文档编辑器(类似Google Docs),用户可以在文档中插入大量字符。每个字符可能包含以下属性:

  • 内在状态(不变的部分):字体、字号、颜色。
  • 外在状态(变化的部分):字符的位置(行号、列号)。

没有使用享元模式的实现:

class Character {private char value;private String font;private int size;private String color;private int row;private int col;public Character(char value, String font, int size, String color, int row, int col) {this.value = value;this.font = font;this.size = size;this.color = color;this.row = row;this.col = col;}public void print() {System.out.println("Character: " + value + ", Font: " + font + ", Size: " + size + ", Color: " + color + ", Position: (" + row + ", " + col + ")");}
}

存在问题:

  1. 内存占用过高:大量相似对象重复存储相同的内在状态。
  2. 性能下降:频繁创建和销毁对象导致内存分配和垃圾回收开销。
  3. 资源浪费:相同的内在状态被重复存储,导致资源浪费。

怎么实现享元模式?

享元模式有哪些构成

  1. Flyweight(享元接口):定义享元对象的接口,通常包含一个操作外在状态的方法。
  2. ConcreteFlyweight(具体享元):实现享元接口,存储内在状态。
  3. FlyweightFactory(享元工厂):负责创建和管理享元对象,确保共享。
  4. Client(客户端):维护外在状态,并在需要时调用享元对象。

【案例】在线文档编辑器 - 改
在这里插入图片描述
Flyweight(享元接口)FontStyle接口。

interface FontStyle {void applyStyle(char value, int row, int col);
}

ConcreteFlyweight(具体享元):具体享元:存储内在状态。

class ConcreteFontStyle implements FontStyle {private String font;private int size;private String color;public ConcreteFontStyle(String font, int size, String color) {this.font = font;this.size = size;this.color = color;}@Overridepublic void applyStyle(char value, int row, int col) {System.out.println("Character: " + value + ", Font: " + font + ", Size: " + size + ", Color: " + color + ", Position: (" + row + ", " + col + ")");}
}

FlyweightFactory(享元工厂)FlyweightFactory 享元工厂,管理共享的享元对象。

class FontStyleFactory {private static final Map<String, FontStyle> styles = new HashMap<>();public static FontStyle getStyle(String font, int size, String color) {String key = font + size + color;FontStyle style = styles.get(key);if (style == null) {style = new ConcreteFontStyle(font, size, color);styles.put(key, style);}return style;}
}

Client(客户端): Character类,使用享元对象。

class Character {private char value;private int row;private int col;private FontStyle style;public Character(char value, int row, int col, FontStyle style) {this.value = value;this.row = row;this.col = col;this.style = style;}public void print() {style.applyStyle(value, row, col);}
}

测试类FlyweightPatternDemo

public class FlyweightPatternDemo {public static void main(String[] args) {FontStyle style1 = FontStyleFactory.getStyle("Arial", 12, "Black");FontStyle style2 = FontStyleFactory.getStyle("Arial", 12, "Black");FontStyle style3 = FontStyleFactory.getStyle("Times New Roman", 14, "Red");Character char1 = new Character('A', 1, 1, style1);Character char2 = new Character('B', 1, 2, style2);Character char3 = new Character('C', 2, 1, style3);char1.print();char2.print();char3.print();System.out.println("Are style1 and style2 the same object? " + (style1 == style2));}
}

输出结果

Character: A, Font: Arial, Size: 12, Color: Black, Position: (1, 1)
Character: B, Font: Arial, Size: 12, Color: Black, Position: (1, 2)
Character: C, Font: Times New Roman, Size: 14, Color: Red, Position: (2, 1)
Are style1 and style2 the same object? true

二、享元模式在框架源码中的运用

Java 中的 Integer 缓存

Java 对 Integer 类型也使用了享元模式,缓存了常用的整数值(默认范围为 -128 到 127)。

实现原理

  • 当使用 Integer.valueOf(int) 方法创建 Integer 对象时,JVM 会检查值是否在缓存范围内。
  • 如果在范围内,则返回缓存中的对象;否则创建新的对象。
Integer i1 = Integer.valueOf(127);
Integer i2 = Integer.valueOf(127);
Integer i3 = Integer.valueOf(128);System.out.println(i1 == i2); // true,i1 和 i2 指向缓存中的同一个对象
System.out.println(i1 == i3); // false,i3 是堆中新创建的对象

享元模式的体现

  • 内在状态:整数值(如 127)。
  • 外在状态:无。
  • 共享机制:通过缓存共享常用的 Integer 对象。

Java 中的 ThreadPoolExecutor

在 Java 的线程池实现中,享元模式的思想被用于复用线程对象。

实现原理

  • 线程池维护一组线程(享元对象),这些线程可以被多个任务复用。
  • 任务(外在状态)被提交到线程池中,由线程池分配线程执行。
ExecutorService executor = Executors.newFixedThreadPool(5);for (int i = 0; i < 10; i++) {executor.submit(() -> {System.out.println("Task executed by " + Thread.currentThread().getName());});
}executor.shutdown();

享元模式的体现

  • 内在状态:线程对象。
  • 外在状态:任务(RunnableCallable)。
  • 共享机制:线程池通过复用线程对象来减少线程创建和销毁的开销。

三、总结

享元模式的优点

  1. 减少内存占用
    • 通过共享内在状态,减少系统中对象的数量,从而降低内存使用。
    • 特别适用于存在大量相似对象的场景。
  2. 提高性能
    • 减少对象的创建和销毁次数,降低内存分配和垃圾回收的开销。
    • 在需要频繁创建和销毁对象的场景中,性能提升尤为明显。
  3. 优化资源管理
    • 集中管理共享对象,避免资源浪费。
    • 便于统一修改和维护共享对象。
  4. 分离关注点
    • 将内在状态和外在状态分离,使系统设计更加清晰。
    • 客户端只需关注外在状态,享元对象负责处理内在状态。

享元模式的缺点

  1. 增加系统复杂性
    • 需要明确区分内在状态和外在状态,增加了设计的复杂性。
    • 客户端需要维护外在状态,并在调用享元对象时传递这些状态。
  2. 线程安全问题
    • 如果享元对象被多个线程共享,可能需要额外的同步机制来保证线程安全。
    • 这会增加代码的复杂性和运行开销。
  3. 不适用于所有场景
    • 如果对象的状态大部分都是变化的,或者对象之间几乎没有共享的状态,享元模式可能不适用。
    • 在这种情况下,强行使用享元模式可能会导致设计过度复杂。

享元模式的适用场景

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

  1. 大量相似对象
    • 系统中存在大量相似对象,且这些对象的状态可以分离为内在状态和外在状态。
    • 例子:
      • 文本编辑器中的字符对象。
      • 游戏中的树木、石头、敌人等对象。
  2. 内存敏感的应用
    • 在内存受限的环境中(如嵌入式系统、移动设备),需要优化内存使用。
    • 例子:
      • 嵌入式系统中的图形界面库。
      • 移动应用中的资源管理。
  3. 性能敏感的应用
    • 在需要高性能的场景中(如游戏、图形渲染),减少对象的创建和销毁开销。
    • 例子:
      • 游戏引擎中的粒子系统。
      • 图形渲染中的材质和纹理管理。
  4. 资源共享的场景
    • 需要集中管理共享资源,避免资源浪费。
    • 例子:
      • 数据库连接池。
      • 线程池。
  5. 不可变对象的场景
    • 对象的内在状态是不可变的,适合被共享。
    • 例子:
      • Java 中的 String 常量池。
      • Java 中的 Integer 缓存。
关键字:seo推广计划_汕头澄海疫情最新消息_怎么申请网站_新闻联播俄罗斯与乌克兰

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: