结构型模式6.享元模式

news2025/1/9 4:08:21

结构型模式

  1. 适配器模式(Adapter Pattern)
  2. 桥接模式(Bridge Pattern)
  3. 组合模式(Composite Pattern)
  4. 装饰器模式(Decorator Pattern)
  5. 外观模式(Facade Pattern)
  6. 享元模式(Flyweight Pattern)
  7. 代理模式(Proxy Pattern)

享元模式(Flyweight Pattern)是一种结构型设计模式,用于减少内存占用,特别是在需要创建大量相似对象的场景中。它通过共享对象来减少内存的消耗,避免创建重复的对象。

享元模式的核心思想:

享元模式的核心思想是:

  • 将对象的状态分为共享状态非共享状态
  • 共享状态存储在享元对象中,多个对象可以共享同一个享元对象。
  • 非共享状态由每个具体的对象自己保存,通常是通过外部传入的方式。

享元模式的关键组成部分:

  1. Flyweight(享元接口):定义可以共享的接口。
  2. ConcreteFlyweight(具体享元类):实现共享状态。
  3. FlyweightFactory(享元工厂类):管理享元对象的创建和共享,确保多个对象共享相同的享元。
  4. UnsharedConcreteFlyweight(非共享享元类):存储每个对象独有的状态。

享元模式的例子:图形编辑器

我们可以通过一个图形编辑器的例子来说明享元模式。假设我们有一个应用需要大量绘制相同类型的图形(如圆形、方形等),但是每个图形的颜色和位置是不同的。如果每个图形都存储相同的颜色、形状等属性,那么会消耗大量内存。

为了节省内存,我们可以使用享元模式,避免为每个图形重复存储相同的信息,而是共享相同的图形数据。

public interface Shape {
    void draw(String color);  // 绘制图形,color是每个图形的非共享状态
}


public class Circle implements Shape {
    private String shapeType;  // 共享状态:形状类型

    public Circle() {
        this.shapeType = "Circle";  // 所有圆形对象共享同一个类型
    }

    @Override
    public void draw(String color) {
        System.out.println("绘制 " + shapeType + ",颜色: " + color);
    }
}


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

public class ShapeFactory {
    private Map<String, Shape> shapeMap = new HashMap<>();  // 缓存已经创建的享元对象

    public Shape getShape(String shapeType) {
        Shape shape = shapeMap.get(shapeType);  // 如果已经创建过该形状,直接返回
        if (shape == null) {
            if (shapeType.equalsIgnoreCase("Circle")) {
                shape = new Circle();  // 创建一个新的Circle对象
            }
            shapeMap.put(shapeType, shape);  // 缓存新创建的享元对象
        }
        return shape;
    }
}


public class Client {
    public static void main(String[] args) {
        ShapeFactory shapeFactory = new ShapeFactory();

        // 创建并绘制不同颜色的圆形
        Shape circle1 = shapeFactory.getShape("Circle");
        circle1.draw("红色");

        Shape circle2 = shapeFactory.getShape("Circle");
        circle2.draw("蓝色");

        Shape circle3 = shapeFactory.getShape("Circle");
        circle3.draw("绿色");

        // 检查是否是同一个Circle对象
        System.out.println(circle1 == circle2);  // 输出:true,说明共享了同一个对象
    }
}

解释:

  • 共享状态:在这个例子中,Circle类的shapeType("Circle")是共享状态,所有的圆形对象都共享同一个Circle对象。
  • 非共享状态:每个draw方法的color参数是非共享状态,每个对象的颜色不同,因此存储在外部传入。
  • 享元工厂(ShapeFactory:负责管理享元对象的创建和共享。它确保相同的形状对象(例如圆形)不会被重复创建,而是通过缓存池重用已创建的对象。
  • 客户端(Client:客户端通过享元工厂获取图形对象,客户端并不关心这些图形是否被共享,只需要关注它们的非共享属性(如颜色)。

优势:

  • 节省内存:通过共享相同的享元对象,可以大大减少内存的使用,特别是在需要创建大量相似对象的场景中。
  • 提高性能:共享对象可以减少对象的创建和销毁,提高性能。
  • 适用于不可变对象:享元模式特别适合用于不可变对象,因为它们的共享状态不能被修改。

劣势:

  • 复杂性增加:引入享元模式后,系统的结构会变得更复杂,需要管理享元对象的创建和缓存。
  • 非共享状态管理:对于每个享元对象的非共享状态,仍然需要额外的管理机制。

总结:

享元模式通过将共享状态提取出来,减少内存消耗,适用于大量相似对象的场景。在设计时需要仔细分离共享和非共享状态,确保享元对象的高效利用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2272386.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring MVC和servlet

1.Spring MVC是Spring框架的一个扩展 2.Spring MVC工作流程 1、用户发送请求至前端控制器DispatcherServlet。 2、DispatcherServlet收到请求调用HandlerMapping处理器映射器。 3、处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找)&#xff0c;生成处理器对象及…

蓝牙架构介绍

架构1&#xff1a;hostcontroller双芯片标准架构 这个标准把蓝牙协议栈分成host和controller两部分&#xff0c;其中host跑在AP上&#xff0c;controller跑在蓝牙模块上&#xff0c;两者之间通过HCI协议进行通信&#xff0c;AP芯片厂商一般会直接采用开源的Bluez来实现Host功能…

MySQL(二)MySQL DDL数据库定义语言

1. MySQL DDL数据库定义语言 1.1. MySQL定义语言 进入MySQL mysql -u root -p(回车后输入密码&#xff0c;即可进入mysq1)1.1.1. 数据库操作 &#xff08;1&#xff09;查看数据库 mysql>show databases;注:MySQL语句分隔符为“&#xff1b;”   mysql库很重要它里面有…

决定系数(R²分数)——评估回归模型性能的一个指标

目录 1.定义 2.计算举例 3. 结果分析 1.定义 R&#xff08;R平方&#xff09;分数&#xff0c;也称为决定系数&#xff0c;是用来评估回归模型性能的一个指标。它表示自变量解释因变量变异性的比例。R分数的取值范围通常在0到1之间&#xff0c;其值越接近1&#xff0c;说明…

node.js内置模块之---stream 模块

stream 模块的作用 在 Node.js 中&#xff0c;stream 模块是一个用于处理流&#xff08;stream&#xff09;的核心模块。流是一种处理数据的抽象方式&#xff0c;允许程序处理大量数据时不会一次性将所有数据加载到内存中&#xff0c;从而提高性能和内存效率。通过流&#xff0…

音视频入门基础:MPEG2-PS专题(5)——FFmpeg源码中,解析PS流中的PES流的实现

一、引言 从《音视频入门基础&#xff1a;MPEG2-PS专题&#xff08;3&#xff09;——MPEG2-PS格式简介》中可以知道&#xff0c;PS流由一个个pack&#xff08;包装&#xff09;组成。一个pack 一个pack_header 一个或多个PES_packet。pack_header中还可能存在system header…

ElasticSearch05-集群搭建

零、文章目录 ElasticSearch05-集群搭建 1、Windows集群 &#xff08;1&#xff09;安装节点 就是把下载的压缩包解压之后复制三个副本 &#xff08;2&#xff09;配置节点 每个文件夹的配置文件config/elasticsearch.yml修改如下node-01 配置如下 cluster.name: myclust…

【服务器项目部署】✈️将本地项目部署到服务器(二)!

目录 &#x1f44b;前言 &#x1f440;一、功能调整 &#x1f331;二、服务部署 &#x1f49e;️三、代码调整 &#x1f37b;四、章末 &#x1f44b;前言 小伙伴们大家好&#xff0c;上篇文章本地实践了如何将本地项目部署到服务器上&#xff0c;从服务器的选择、服务器环境…

挖掘建模之分类与预测

根据挖掘目标和数据形式可以建立分类与预测、聚类分析、关联规则、时序模式、偏差检测、智能推荐等模型&#xff0c;帮助企业提取数据中蕴含的商业价值&#xff0c;提高企业的竞争力。 1.分类与预测 就餐饮企业而言&#xff0c;经常会碰到这样的问题&#xff1a; 1&…

安卓入门十三 常用功能模块一RxJava

响应式编程RxJava 响应式编程&#xff1a;使用RxJava库实现响应式编程范式&#xff0c;提供更简洁、易于维护的异步编程方式。 异步编程的简洁性&#xff1a;响应式编程提供了一种简洁、流畅的方式来处理异步任务。通过使用操作符和线程调度器&#xff0c;可以将异步操作串联…

【LeetCode】:最长乘积等价子数组【简单】

https://leetcode.cn/problems/maximum-subarray-with-equal-products/description/ 以下是解决这道题的详细思路&#xff1a; 一、理解题目要求 题目给定一个由正整数组成的数组 nums&#xff0c;需要找出其中最长的“乘积等价子数组”的长度。一个数组 arr 被称为“乘积等…

Android使用DataBinding和Merge引发的血案

Android使用DataBinding和Merge引发的血案 1.前言&#xff1a; 相信Databinding和Merge大家都不陌生&#xff0c;今天讲解的是Databinding和Merge一起使用遇到的问题&#xff0c;在父布局使用&#xff0c;引用的布局使用Merge会导致id找不到&#xff0c;运行时直接崩溃了&…

JS (node) 的 ACM 模式 + debug方法 (01背包为例)

文章目录 JS 的 ACM 模式输入处理 JS dubug (01背包为例)动态输入在本地通过 Node.js 运行和调试 硬编码 Hard CodingVS Code JS 的 ACM 模式 在 JavaScript 中&#xff0c;ACM 模式一般通过 Node.js 的 readline 模块实现。 输入处理 使用 readline 模块监听输入。 将每行输…

【MySQL 保姆级教学】用户管理和数据库权限(16)

数据库账户管理是指对数据库用户进行创建、修改和删除等操作&#xff0c;以控制用户对数据库的访问权限。通过账户管理&#xff0c;可以设置用户名、密码、主机地址等信息&#xff0c;确保数据库的安全性和可控性。例如&#xff0c;使用 CREATE USER 创建用户&#xff0c;ALTER…

HTML——56.表单发送

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>表单发送</title></head><body><!--注意&#xff1a;1.表单接收程序&#xff0c;放在服务器环境中(也就是这里的www文件目录中)2.表单发送地址&#x…

el-table行列转换简单版,仅限单行数据

原始数据格式如下&#xff0c;如果不是此格式&#xff0c;请转换成以下格式在进行以下操作 [{ label: name, value: Tom },{ label: age, value: 25 },{ label: country, value: UK } ]代码如下 <template><el-table :data"tableData" style"width: …

OpenGL材质系统和贴图纹理

上一篇文章当中笔者为大家介绍了风氏光照模型&#xff0c;相信大家也发现了光照着色器当中有设置有很多控制光照强度的参数&#xff0c;而所谓的材质系统就是我们可以人为的去调节这些参数&#xff0c;让一个物体的反光效果能够更加接近我们现实生活当中的一些物体。 材质系统…

【mybatis】Mybatis整体架构解析

从本篇开始我们开始学习mybatis的系列源码&#xff0c;主要的主题可能就是四个方面 从整体把握mybatis系统架构通过一个查询SQL 源码解析核心流程mybatis的缓存机制-源码级别mybatis的插件机制-源码级别spring是如何整合的mybatis框架的 1.整体架构 上述是mybatis的源码&…

stm32 智能语音电梯系统

做了个stm32智能语音控制的电梯模型&#xff0c;总结一下功能&#xff0c;源码用ST的HAL库写的&#xff0c;整体流程分明。 实物图 这个是整个板子的图片&#xff0c;逻辑其实并不复杂&#xff0c;只是功能比较多&#xff0c;在我看来都是一些冗余的功能&#xff0c;但也可能是…

Git 部署

参考&#xff1a;手把手教你入门Git — Git使用指南&#xff08;Linux&#xff09; 需要说明的是&#xff1a; 1、服务器linux系统中一般使用master分支&#xff0c;但github现在流行的是main分支&#xff1b; 解决方案是修改master分支位main分支 git branch -m master mai…