十一、享元模式

  • 目的 : 运用共享技术有效地支持大量细粒度的对象。
  • 核心 : 区分对象的内部状态 (可共享的、不变的)和外部状态(不可共享的、变化的)。创建享元工厂管理共享的内部状态,客户端使用时传入外部状态。
  • 场景 : 游戏中有大量相同类型的对象(如子弹、树木、士兵)、文本编辑器需要渲染大量字符(如字母、数字、符号)等。

首先有一个享元对象类

java 复制代码
package flyweight;

public class Letter {
	private String name;

	public Letter(String name){
		this.name = name;
	}

	public String getName(){
		return this.name;
	}
}

然后是享元工厂类

java 复制代码
package flyweight;

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

public class LetterFactory {
	private Map<String, Letter> map;	// 对象池
	private static LetterFactory instance = new LetterFactory();  // 1 私有静态实例 instance,通过静态方法 getInstance() 获取。

	private LetterFactory(){
		map = new HashMap<>();	//  2  私有构造函数,禁止外部直接实例化。
	}

	public static  LetterFactory getInstance(){		//  3  确保 LetterFactory 全局只有一个实例。
		return instance;
	}

	public synchronized void add(Letter letter){	 // 确保同名 Letter 只保存一份
		if(letter != null && !map.containsKey(letter.getName())){
			map.put(letter.getName(), letter);		 //	 存入缓存
		}

		System.out.println("map.size ==== " + map.size()); //通过对象池大小检验:是否同名 Letter 只保存一份
	}

	public Letter get(String name){
		return map.get(name);			// 从缓存中获取对象,避免重复创建
	}
}

函数入口

java 复制代码
package flyweight;

public class MainTest {
	public static void main(String[] args) {
		LetterFactory factory = LetterFactory.getInstance();	// 获取单例
		String word = "success";

		addLetterByName(factory, word);
		getLetter(factory, word);
	}

	static void addLetterByName(LetterFactory factory, String word) {
		for (char c : word.toCharArray()) {						// 遍历字符串的每个字符
			factory.add(new Letter(c + ""));					// 创建 Letter 对象并存入工厂,c + "" 的作用是将 char 类型转换为 String 类型
		}
	}

	static void getLetter(LetterFactory factory, String word) {
		for (char c : word.toCharArray()) {
			System.out.println(factory.get(c + ""));			// 从缓存中获取对应的 对象并打印
		}
	}
}

终端输出:

复制代码
map.size ==== 1  // 添加 s
map.size ==== 2  // 添加 u  
map.size ==== 3  // 添加 c
map.size ==== 3  // 第二个 c,已存在,size不变
map.size ==== 4  // 添加 e
map.size ==== 4  // 第二个 s,已存在,size不变  
map.size ==== 4  // 第三个 s,已存在,size不变

flyweight.Letter@4aa298b7  // s
flyweight.Letter@7d4991ad  // u
flyweight.Letter@28d93b30  // c
flyweight.Letter@28d93b30  // c (复用)
flyweight.Letter@1b6d3586  // e  
flyweight.Letter@4aa298b7  // s (复用)
flyweight.Letter@4aa298b7  // s (复用)

LetterFactory 和 Letter 是聚合关系,Letter 可以独立存在;

LetterFactory 和 map 是组合关系,map 是 LetterFactory 的组成部分。

相关推荐
16月6日-晴3 分钟前
Java面向对象进阶—static
java·开发语言
xiaohaiAIgeo44 分钟前
【2026年】ASHRAE 110与EN 14175通风柜测试标准对比:进口与国产品牌性能差距
java·前端·数据库·科普知识
AI人工智能+电脑小能手2 小时前
大白话说Java设计模式-08-建造者模式(业务实战篇)
java·设计模式·建造者模式·架构设计·对象构建
xbgRS2 小时前
java中的线程
java
ChaHae-In3 小时前
MyBatis入门操作
java·mybatis
xcLeigh3 小时前
Go入门:短变量声明的陷阱与最佳实践
java·redis·golang·教程·变量
青山木3 小时前
Hot 100 --- 最小栈
java·数据结构·算法·leetcode
疯狂打码的少年3 小时前
【数据结构】栈的应用:表达式求值(后缀表达式)
java·数据结构·笔记·算法
szephyr3 小时前
腾讯云 ADP 智能体的 Skills 版本回滚总是回到旧配置,是缓存没清还是版本管理没开?
java·缓存·腾讯云
云烟成雨TD3 小时前
Micrometer 系列【39】链路追踪:入门案例 | 环境准备
java·云原生·链路追踪