java设计模式:03-06-享元模式

享元模式(Flyweight Pattern)

享元模式(Flyweight Pattern)是一种结构型设计模式,它通过共享技术来有效地支持大量细粒度对象的重用。享元模式避免了在相似对象间的高开销,通过共享尽可能多的状态来尽量减少内存使用。享元模式的核心思想是将对象的状态分为内在状态(共享部分)和外在状态(不共享部分),内在状态可以被多个对象共享,而外在状态则需要在对象之间独立维护。

享元模式的应用场景

  • 系统中有大量相似对象,由于重复而造成了大量的内存开销。
  • 对象的状态可以分为内在状态和外在状态,其中内在状态可以共享。
  • 需要支持大量细粒度对象的共享,以减少内存开销,如文本编辑器中的字符对象、图形应用中的图形对象等。

享元模式的实现方式

1. 传统实现方式

思想:创建一个享元工厂,用于创建和管理享元对象。享元工厂确保共享享元对象的唯一实例,避免重复创建相同的对象。

实现方式:

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

// 享元接口
interface Flyweight {
    void operation(String extrinsicState);
}

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

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

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

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

    public Flyweight getFlyweight(String key) {
        if (!flyweights.containsKey(key)) {
            flyweights.put(key, new ConcreteFlyweight(key));
        }
        return flyweights.get(key);
    }
}

// 客户端代码
public class FlyweightPattern {
    public static void main(String[] args) {
        FlyweightFactory factory = new FlyweightFactory();
        Flyweight flyweight1 = factory.getFlyweight("A");
        Flyweight flyweight2 = factory.getFlyweight("B");
        Flyweight flyweight3 = factory.getFlyweight("A");

        flyweight1.operation("First Call");
        flyweight2.operation("Second Call");
        flyweight3.operation("Third Call");
    }
}

优点:

  • 减少对象的创建,降低内存消耗。
  • 提高系统性能,通过共享技术避免对象的重复创建。
  • 提高了系统的可扩展性,可以很方便地新增具体享元类。

缺点:

  • 增加系统的复杂性,需要维护一个享元对象的池。
  • 享元模式使得系统不容易理解和维护,因为它引入了众多的细粒度对象。
  • 可能不适用于内在状态无法分离的情况。
2. 使用多线程和缓存优化的享元模式

思想:通过使用多线程和缓存技术来优化享元模式,确保享元工厂在高并发环境下的性能和正确性。

实现方式:

java 复制代码
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

// 享元接口
interface Flyweight {
    void operation(String extrinsicState);
}

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

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

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

// 享元工厂
class FlyweightFactory {
    private ConcurrentMap<String, Flyweight> flyweights = new ConcurrentHashMap<>();

    public Flyweight getFlyweight(String key) {
        flyweights.computeIfAbsent(key, k -> new ConcreteFlyweight(k));
        return flyweights.get(key);
    }
}

// 客户端代码
public class OptimizedFlyweightPattern {
    public static void main(String[] args) {
        FlyweightFactory factory = new FlyweightFactory();
        Flyweight flyweight1 = factory.getFlyweight("A");
        Flyweight flyweight2 = factory.getFlyweight("B");
        Flyweight flyweight3 = factory.getFlyweight("A");

        flyweight1.operation("First Call");
        flyweight2.operation("Second Call");
        flyweight3.operation("Third Call");
    }
}

优点:

  • 线程安全:使用并发容器和原子操作,确保在高并发环境下的正确性。
  • 缓存优化:使用缓存技术减少对象的重复创建,提高性能。

缺点:

  • 增加了代码复杂度:多线程和缓存技术的引入使得代码更加复杂。
  • 可能增加内存消耗:缓存技术可能会增加一定的内存开销。

总结

实现方式 优点 缺点
传统实现方式 减少对象创建,降低内存消耗,提高系统性能,系统可扩展性高 增加系统复杂性,需要维护享元对象池,不易理解和维护
使用多线程和缓存优化的享元模式 线程安全,性能高,减少对象的重复创建 代码复杂度增加,多线程和缓存技术的引入增加了系统复杂性

选择哪种实现方式应根据具体的需求和系统的复杂度来决定。如果系统中有大量的相似对象并且需要在高并发环境下使用,可以选择使用多线程和缓存优化的享元模式。如果系统的并发需求不高,可以选择传统实现方式。

相关推荐
Dovis(誓平步青云)1 分钟前
总用电下降了,为什么家庭能源看板仍然提示异常
java·开发语言·数据库·人工智能·算法·电脑·能源
程序猿乐锅2 分钟前
【从0-1学习Python | 第四篇】Python 字符串和元组
java·开发语言·笔记·后端·python·学习
拆房老料5 分钟前
【第四部分:Agentic 智能体设计模式】15.为什么 Agent 也需要设计模式
人工智能·设计模式·ai·ai-native
开开心心就好5 分钟前
Windows视频播放器推荐,精简版体积更小
java·服务器·开发语言·eclipse·pdf·ocr·音视频
Rain的Java大神之路28 分钟前
10 万人抢 2000 个座位,电影票选座系统怎么防超卖?一文讲透大厂高频场景题
java·后端·面试
砚底藏山河34 分钟前
量化新手误区:因子计算与行情数据的工程化解耦
java·数据库·python·金融
威哥爱编程36 分钟前
【AI全栈12-07】Spring Boot 用 Agent 自动完成多步运营任务
java·spring boot·后端
未秃头的程序猿39 分钟前
我用 Spring AI + MCP 把公司内部系统接给了 AI,过程没想象中顺利
java·后端
m0_587383001 小时前
碰碰好评卡功能落地实战 从需求梳理到上线部署全流程实操指南
java·linux·服务器·前端·javascript·vue.js·人工智能
geovindu1 小时前
rust: Chain of Responsibility Pattern (续)
开发语言·后端·设计模式·rust·责任链模式·行为模式