• 初识设计模式 - 享元模式


    简介

    古代的活字印刷术就有点像享元模式,活字印刷就是将每个字模做出来,再印刷时再选取需要的字模到印刷板上,这样就构成了一页书的印刷板。这样的活字印刷大大提升了效率,减少了印刷板的空间。

    在享元模式中,存储共享实例对象的地方称为享元池(Flyweight Pool)。类比到上述的活字印刷术中,放置字模的地方就是享元池。

    享元模式能做到共享的关键是区分了内部状态和外部状态,它们的简单释义是:

    • 内部状态:存储在享元对象内部且不跟随环境变化而改变的状态,内部状态可以在对象之间共享
    • 外部状态:通常由客户端保存,当需要时再传入享元对象中的状态,会跟随环境变化而改变,不可以在对象之间共享。

    典型示例

    一个典型的享元工厂类的代码示例如下:

    public class FlyweightFactory {
    // 使用 HashMap 定义享元池
    private final HashMap flyweights = new HashMap<>();
    public Flyweight getFlyweight(String key) {
    // 如果对象存在,直接从享元池中获取
    if (flyweights.containsKey(key)) {
    return (Flyweight) flyweights.get(key);
    } else {
    // 如果对象不存在,先创建一个新的对象添加到享元池中,然后返回
    Flyweight fw = new ConcreteFlyweight();
    flyweights.put(key, fw);
    return fw;
    }
    }
    }

    一个典型的享元抽象类的代码示例如下:

    public abstract class Flyweight {
    // 内部状态作为成员对象,同一个享元对象其内部状态是一致的
    protected Object intrinsicState;
    public Flyweight(Object intrinsicState) {
    this.intrinsicState = intrinsicState;
    }
    public void operation(Object extrinsicState) {
    // 外部状态在使用时由外部提供,每一次都可以不同
    }
    }

    通常,实际会根据业务情况定义具体享元类,代码示例如下:

    public class ConcreteFlyweight extends Flyweight {
    public ConcreteFlyweight(Object intrinsicState) {
    super(intrinsicState);
    }
    @Override
    public void operation(Object extrinsicState) {
    // 结合内部状态 intrinsicState 以及方法参数传入的 extrinsicState 完成具体逻辑
    }
    }

    总结

    优点

    享元模式的主要优点如下:

    • 极大地减少内存中对象的数量,节约了系统资源,提高了系统性能
    • 享元模式的外部状态相对独立,而且不会影响其内部状态,从而使得享元对象可以在不同的环境中被共享

    缺点

    享元模式的主要缺点如下:

    • 享元模式需要分离出内部状态和外部状态,从而使得系统变得复杂,这使得程序的逻辑复杂化
    • 为了使对象可以共享,享元对象需要将部分状态外部化,而读取外部状态将使得运行时间变长

    适用场景

    享元模式的适用场景如下:

    • 一个系统有大量相同或相似的对象,造成内存大量耗费

    源码

    在 Java 类库中的 String 类就使用了享元模式,使用字面量创建的对象是共享的,而不会重新为此分配内存空间。

  • 相关阅读:
    【云岚到家】-day02-2-客户管理-认证授权
    线程版服务器实现(pthread_server)
    Spring在业务中常见的使用方式
    T113-S3-buildroot文件系统tar解压缩gz文件
    【vue基础】黑马vue视频笔记(四)
    创新案例分享 | 运维完善税务局信息管理系统,保障系统稳定高效运行
    iwebsec靶场 SQL注入漏洞通关笔记8- 大小写过滤注入
    Java 22正式发布,一文了解全部新特性
    Java使用IReport导出复杂报表
    Poppler in path for pdf2image
  • 原文地址:https://www.cnblogs.com/fatedeity/p/16783274.html