享元模式模式简介

2023-09-20 09:15:21

概念

享元模式(Flyweight pattern)是一种结构型设计模式,旨在通过共享对象来减少内存使用和提高性能。它通过将对象的状态分为可共享的内部状态和不可共享的外部状态,来实现对象的共享。内部状态可以被多个对象共享,而外部状态则取决于具体的对象。通过共享内部状态,可以减少系统中相似对象的数量,从而节省内存空间。

特点

  1. 减少内存占用:通过共享内部状态,减少了相似对象的数量,降低了内存占用。
  2. 提高性能:减少了创建相似对象的开销,提高了系统的性能。
  3. 分离内部状态和外部状态:内部状态可以共享,外部状态是独立的,客户端可以自行设置。

优点

  1. 减少内存占用:通过共享内部状态,减少了相似对象的数量,降低了内存占用。
  2. 提高性能:减少了创建相似对象的开销,提高了系统的性能。
  3. 简化对象结构:通过将状态分离,简化了对象的结构,使得对象更加轻量级。

缺点

  1. 对象共享可能导致线程安全问题:如果多个线程同时访问共享对象,并修改了外部状态,可能会导致线程安全问题。
  2. 增加了代码复杂性:为了实现对象的共享和分离状态,需要引入额外的逻辑,增加了代码的复杂性。

适用场景

  1. 对象数量庞大且相似:当系统中存在大量相似的对象,并且这些对象的区别仅在于它们的内部状态时,可以考虑使用享元模式。
  2. 需要缓存对象的应用:当需要缓存对象以提高性能时,可以使用享元模式来共享对象。

实现方式

  1. 内部状态和外部状态分离:将对象的状态分为内部状态和外部状态,内部状态可以共享,外部状态是独立的。
  2. 对象池:通过维护一个对象池来管理可共享的对象,客户端从对象池中获取对象,并设置外部状态。
  3. 使用工厂模式:可以结合工厂模式来创建享元对象,工厂负责管理对象的共享和创建。

实现代码:

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);
        System.out.println("Extrinsic State: " + extrinsicState);
        // 执行具体操作
    }
}

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

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



public class Main {

    public static void main(String[] args) {
        FlyweightFactory factory = new FlyweightFactory();

        // 获取享元对象
        Flyweight flyweight1 = factory.getFlyweight("key1");
        Flyweight flyweight2 = factory.getFlyweight("key1");

        // 调用享元对象的操作方法,传入外部状态
        flyweight1.operation("state1");
        flyweight2.operation("state2");
    }


}

在这个简单的示例代码中,我们创建了一个具体享元类ConcreteFlyweight,它包含了内部状态intrinsicStateFlyweightFactory是享元工厂类,它维护了一个享元对象的池,并通过getFlyweight方法返回具体的享元对象。内部状态在具体享元对象内部管理,而外部状态由客户端传入。

客户端代码中,首先通过工厂类获取两个享元对象flyweight1flyweight2,他们共享了同一个享元对象,然后分别调用它们的operation方法,传入外部状态。从而实现了共享内部状态,同时处理各自的外部状态。

更多推荐

Kafka 时间轮算法

文章目录前言Java任务调度TimerDelayedWorkQueue的最小堆实现时间轮Kafka中时间轮实现前言Kafka中存在大量的延时操作。发送消息-超时+重试机制的延时。ACKS确认机制的延时。Kafka并没有使用JDK自带的Timer或者DelayQueue来实现延迟的功能,而是基于时间轮自定义了一个用于实现

Kafka核心原理

一、kafka安装步骤(1)配置profile文件vim/etc/profile//KAFKAexportKAFKA_HOME=/opt/soft/kafka212exportPATH=$KAFKA_HOME/bin:$PATHsource/etc/profile(2)创建kfkdata目录cd/opt/soft/ka

最佳实践:TiDB 业务写变慢分析处理

作者:李文杰数据架构师,TUG广州地区活动组织者在日常业务使用或运维管理TiDB的过程中,每个开发人员或数据库管理员都或多或少遇到过SQL变慢的问题。这类问题大部分情况下都具有一定的规律可循,通过经验的积累可以快速的定位和优化。但是有些情况下不一定很好排查,尤其涉及到内核调优等方向时,如果事先没有对各个组件的互访关系、

实现高效消息传递:使用RabbitMQ构建可复用的企业级消息系统

文章目录前言1.安装erlang语言2.安装rabbitMQ3.内网穿透3.1安装cpolar内网穿透(支持一键自动安装脚本)3.2创建HTTP隧道4.公网远程连接5.固定公网TCP地址5.1保留一个固定的公网TCP端口地址5.2配置固定公网TCP端口地址前言RabbitMQ是一个在AMQP(高级消息队列协议)基础上完

GODIVA论文阅读

论文链接:GODIVA:GeneratingOpen-DomaInVideosfromnAturalDescriptions文章目录摘要引言相关工作Video-to-videogenerationText-to-imagegenerationText-to-videogenerationGODIVA方法逐帧视频自动编码

【Java 基础篇】Executors工厂类详解

在多线程编程中,线程池是一项重要的工具,它可以有效地管理和控制线程的生命周期,提高程序的性能和可维护性。Java提供了java.util.concurrent包来支持线程池的创建和管理,而Executors工厂类是其中的一部分,它提供了一些方便的方法来创建不同类型的线程池。本文将详细介绍Executors工厂类的使用方

Android 使用Camera1实现相机预览、拍照、录像

1.前言本文介绍如何从零开始,在Android中实现Camera1的接入,并在文末提供Camera1Manager工具类,可以用于快速接入Camera1。AndroidCamera1API虽然已经被Google废弃,但有些场景下不得不使用。并且Camera1返回的帧数据是NV21,不像Camera2、CameraX那样

【C++】C 语言 和 C++ 语言中 const 关键字分析 ② ( const 常量分配内存时机 | const 常量在编译阶段分配内存 )

文章目录一、const常量内存分配时机二、使用如下代码验证const常量内存分配时机三、分析验证结果-const常量在编译阶段分配内存一、const常量内存分配时机在上一篇博客中,讲到了获取const常量的地址,代码如下://定义常量//该常量定义在了符号表中//符号表不在内存四区中,是另外一种机制constinta=

Pytorch 深度学习实践 day01(背景)

准备线性代数,概率论与数理统计,Python理解随机变量和分布之间的关系人类智能和人工智能人类智能分为推理和预测推理:通过外界信息的输入,来进行的推测预测:例如,看到一个真实世界的实体,把它和抽象概念联系起来人工智能(机器学习):把以前我们用来做推理或预测的大脑,变成算法在机器学习和深度学习中,常用的是监督学习,即有标

【深度学习实验】线性模型(三):使用Pytorch实现简单线性模型:搭建、构造损失函数、计算损失值

目录一、实验介绍二、实验环境1.配置虚拟环境2.库版本介绍三、实验内容0.导入库1.定义线性模型linear_model2.定义损失函数loss_function3.定义数据4.调用模型5.完整代码一、实验介绍使用Pytorch实现线性模型搭建构造损失函数计算损失值二、实验环境本系列实验使用了PyTorch深度学习框架

针对敏感数据的安全转录服务

即便在新冠肺炎疫情期间,继续保持了最高级别的机密性新冠肺炎疫情带来的各种限制向所有服务提供商提出了挑战,促使提供商们想方设法采取更富想象力的新方法来满足客户的需求。澳鹏采用了一种由两种方案组成的工作机制,服务于客户机密材料的转录,既实现了高度的机密性,又保护了员工的安全。大多数转录服务提供商都会采用基本的安全措施,如员

热文推荐