23种设计模式-结构型模式之享元模式(Java版本)

Java 享元模式(Flyweight Pattern)详解

🦋 什么是享元模式?

享元模式是一种结构型模式 ,它通过共享相同的对象 来减少内存消耗,适用于大量细粒度对象的场景。关键思想是缓存重复出现的对象,避免重复创建。


🧠 使用场景

  • 系统中存在大量相似对象
  • 对象的状态可分为内部状态(可共享)外部状态(不可共享)
  • 对象创建代价高,影响性能

🏗️ 模式结构

  • Flyweight(享元抽象类):定义共享接口
  • ConcreteFlyweight(具体享元类):实现共享逻辑,存储内部状态
  • FlyweightFactory(享元工厂):管理享元对象池,复用已有对象

✅ 示例:围棋棋子池

享元接口(Flyweight)

复制代码
public interface ChessPiece {
    void display(String position);
}

具体享元(ConcreteFlyweight)

复制代码
public class BlackChess implements ChessPiece {
    @Override
    public void display(String position) {
        System.out.println("⚫ 黑棋,位置:" + position);
    }
}

public class WhiteChess implements ChessPiece {
    @Override
    public void display(String position) {
        System.out.println("⚪ 白棋,位置:" + position);
    }
}

享元工厂(FlyweightFactory)

复制代码
import java.util.HashMap;
import java.util.Map;

public class ChessFactory {
    private static final Map<String, ChessPiece> cache = new HashMap<>();

    public static ChessPiece getChess(String color) {
        ChessPiece piece = cache.get(color);
        if (piece == null) {
            if (color.equalsIgnoreCase("black")) {
                piece = new BlackChess();
            } else if (color.equalsIgnoreCase("white")) {
                piece = new WhiteChess();
            }
            cache.put(color, piece);
        }
        return piece;
    }
}

客户端调用

复制代码
public class Client {
    public static void main(String[] args) {
        ChessPiece black1 = ChessFactory.getChess("black");
        ChessPiece black2 = ChessFactory.getChess("black");
        ChessPiece white1 = ChessFactory.getChess("white");

        black1.display("A1");
        black2.display("B2");
        white1.display("C3");

        System.out.println("black1 与 black2 是否为同一对象?" + (black1 == black2)); // true
    }
}

🧩 优点

  • 大量相似对象可以复用,节省内存,提升性能

  • 将共享与非共享状态区分清晰,结构更清晰

⚠️ 缺点

  • 系统逻辑变复杂,需要区分内部与外部状态

  • 不适合对象差异性大的情况

✅ 使用建议

  • 适用于如下情况:

  • 游戏对象池(如子弹、精灵)

  • 数据库连接池、线程池

  • 文本编辑器中的字体对象共享

相关推荐
亦暖筑序19 分钟前
AgentScope-Java 入门:用 SSE 展示评审任务进度
java·agent·ai编程
玖玥拾24 分钟前
C# 语言进阶(十三)网络 DLL 库分层设计
服务器·开发语言·网络·网络协议·c#
Kel29 分钟前
管道、IPC、Socket:你以为的三种技术,其实是同一件事
javascript·设计模式·node.js
2601_9498163530 分钟前
C++内存对齐与结构体填充深度精讲:底层规则、内存裁剪、适配优化与工程避坑
开发语言·arm开发·c++
卓怡学长33 分钟前
w261springboot基于web学校课程管理系统
java·数据库·spring boot·spring·intellij-idea
shuoshuohaohao34 分钟前
《JavaWeb --2》
java
浩瀚地学35 分钟前
【面试算法笔记】0105-数组-螺旋矩阵
java·开发语言·笔记·算法·面试
AI人工智能+电脑小能手42 分钟前
【大白话说Java面试题 第169题】【07_Redis篇】第5题:如何保证缓存一致性?
java·redis·延迟双删·缓存一致性·双写一致性
Geek-Chow1 小时前
Mobile App Certificate Pinning: Underlying Principle and a Swift Example
开发语言·ios·swift·安全架构
SimonKing1 小时前
Spring I18N 底层源码大揭秘:你的 MessageSource 到底是怎么找到配置的?
java·后端·程序员