当前位置: 首页 > article >正文

设计模式-结构型-享元模式

1. 享元模式概述

享元模式(Flyweight Pattern)是一种结构型设计模式,主要用于减少对象的数量,以降低内存占用和提高性能。它通过共享相似对象来避免创建大量相同的实例,适用于需要大量创建重复对象的场景,例如文本编辑器中的字符对象、图形编辑软件中的形状对象等。

享元模式的核心思想:

  • 内部状态(Intrinsic State):可以共享的状态,不会随环境改变,如字体的字形。
  • 外部状态(Extrinsic State):不能共享的状态,需要在运行时传入,如字符的位置。

2. 享元模式的结构

享元模式的典型结构如下:

  • Flyweight(享元接口):定义一个方法用于接收外部状态,并执行相应的逻辑。
  • ConcreteFlyweight(具体享元类):实现享元接口,存储内部状态,并通过外部状态完成功能。
  • FlyweightFactory(享元工厂):用于管理享元对象,提供共享机制,避免重复创建相同对象。
  • Client(客户端):使用享元对象,并传递外部状态。

3. Python 实现享元模式

示例:文字处理系统

假设我们要实现一个文本编辑器,每个字符都有自己的格式(字体、大小、颜色等),但字符的形状是共享的(如‘A’、‘B’等),这正是享元模式的应用场景。

(1) 享元类

class CharacterFlyweight:"""享元类,存储不可变的内部状态(字符)"""def __init__(self, char):self.char = char  # 共享的内部状态def display(self, font, size, color, position):"""显示字符,接收外部状态"""print(f"Character: {self.char}, Font: {font}, Size: {size}, Color: {color}, Position: {position}")

(2) 享元工厂

class CharacterFlyweightFactory:"""享元工厂,管理共享的CharacterFlyweight对象"""_flyweights = {}  # 享元对象池@staticmethoddef get_flyweight(char):"""获取享元对象,若不存在则创建"""if char not in CharacterFlyweightFactory._flyweights:CharacterFlyweightFactory._flyweights[char] = CharacterFlyweight(char)return CharacterFlyweightFactory._flyweights[char]

(3) 客户端

class TextEditor:"""客户端类,使用享元对象并传入外部状态"""def __init__(self):self.characters = []  # 存储字符及其格式信息def add_character(self, char, font, size, color, position):"""添加字符到文本"""flyweight = CharacterFlyweightFactory.get_flyweight(char)  # 获取享元对象self.characters.append((flyweight, font, size, color, position))def render(self):"""渲染文本"""for flyweight, font, size, color, position in self.characters:flyweight.display(font, size, color, position)

(4) 测试代码

if __name__ == "__main__":editor = TextEditor()# 添加字符,并指定不同的外部状态editor.add_character('A', "Arial", 12, "Black", (0, 0))editor.add_character('B', "Times New Roman", 14, "Red", (10, 0))editor.add_character('A', "Verdana", 16, "Blue", (20, 0))  # 共享 'A' 对象editor.render()# 查看享元对象池print("Flyweight Objects in Factory:", list(CharacterFlyweightFactory._flyweights.keys()))

4. 运行结果

Character: A, Font: Arial, Size: 12, Color: Black, Position: (0, 0)
Character: B, Font: Times New Roman, Size: 14, Color: Red, Position: (10, 0)
Character: A, Font: Verdana, Size: 16, Color: Blue, Position: (20, 0)
Flyweight Objects in Factory: ['A', 'B']

可以看到:

  • A 被复用,只创建了一次,而不同外部状态由客户端管理。
  • B 作为新字符被单独创建。
  • 享元工厂管理已创建的字符,并提供共享机制。

5. 享元模式的优缺点

优点

节省内存:减少相同对象的重复创建,降低内存消耗。
提高性能:通过对象复用减少创建时间,提高程序运行效率。
分离状态:内部状态和外部状态分离,增强系统的灵活性。

缺点

增加系统复杂度:享元工厂和对象管理逻辑较复杂,需要维护共享对象池。
适用场景受限:如果对象的内部状态较少或不易分离,享元模式可能不适用。
外部状态管理负担:外部状态由客户端维护,可能导致代码复杂度增加。


6. 适用场景

  • 文本处理:如文字编辑器,每个字符的形状相同但样式不同。
  • 图形系统:如绘图软件,重复绘制相同的形状但不同位置。
  • 游戏开发:如子弹、NPC等对象的复用,提高渲染效率。
  • 数据缓存:如数据库连接池、线程池等,避免重复创建消耗资源。

7. 总结

享元模式是一种优化性能和内存使用的模式,适用于大量重复对象的场景。通过分离内部状态和外部状态,它能有效减少内存占用,提高系统性能。然而,它也会增加系统复杂度,需要权衡使用场景。在 Python 中,利用字典缓存和 .api 调用可以高效地实现享元模式。

相关文章:

设计模式-结构型-享元模式

1. 享元模式概述 享元模式(Flyweight Pattern)是一种结构型设计模式,主要用于减少对象的数量,以降低内存占用和提高性能。它通过共享相似对象来避免创建大量相同的实例,适用于需要大量创建重复对象的场景,…...

嵌入式八股文(四)计算机网络篇

第一章 基础概念 1. 服务 指网络中各层为紧邻的上层提供的功能调用,是垂直的。包括面向连接服务、无连接服务、可靠服务、不可靠服务。 2. 协议 是计算机⽹络相互通信的对等层实体之间交换信息时必须遵守的规则或约定的集合。⽹络协议的三个基本要素:语法、…...

用deepseek学大模型04-机器学习建模过程

https://metaso.cn/s/7tEmBHr 目前已经学完深度学习的数学基础,给出机器学习建模的基本过程 好的,我现在需要回答用户的问题:已经学完深度学习的数学基础,现在要给出机器学习建模的基本过程。我需要结合我搜索到的资料来构建一个详…...

基于单片机的多功能门铃控制系统设计(论文+源码)

1功能设计 本课题为基于单片机的多功能门铃控制系统设计,主要结合单片机技术,门铃控制技术进行设计,在多功能门铃控制系统的设计中,将其主要的设计功能确定如下: (1)可以实现门铃的基础功能…...

使用Keras构建图像分类模型的入门指南

本人主页:机器学习司猫白 机器学习专栏:机器学习实战 PyTorch入门专栏:PyTorch入门 深度学习实战:深度学习 ok,话不多说,我们进入正题吧 一、Keras框架简介 1.1 什么是Keras? Keras是一个高层神经网络API,最初由Google工程师Franois Chollet开发,具有以下核心特点:…...

docker 运行 芋道微服务

jar包打包命令 mvn clean install package -Dmaven.test.skiptrue创建文件夹 docker-ai 文件夹下放入需要jar包的文件夹及 docker-compose.yml 文件 docker-compose.yml 内容:我这里的是ai服务,所以将原先的文件内容做了变更,你们需要用到什…...

win10 系统 自定义Ollama安装路径 及模型下载位置

win10 系统 自定义Ollama安装路径 及模型下载位置 由于Ollama的exe安装软件双击安装的时候默认是在C盘,以及后续的模型数据下载也在C盘,导致会占用C盘空间,所以这里单独写了一个自定义安装Ollama安装目录的教程。 Ollama官网地址&#xff1…...

整合Salesmart/WhatsApp、开源Odoo模块和Deepseek AI能力,实现针对国外客户的智能客服和个性化推荐服务

一、项目背景 本文提出了一套针对软管制造公司的智能客服与个性化推荐系统实施方案,旨在通过整合开源Odoo模块、Salesmart/WhatsApp以及Deepseek AI能力,打造一个724小时不间断服务的智能化平台,专注于服务国外客户。方案围绕实现不间断服务…...

人工智能基础之数学基础:01高等数学基础

函数 极限 按照一定次数排列的一列数:“,“,…,"…,其中u 叫做通项。 对于数列{Un}如果当n无限增大时,其通项无限接近于一个常数A,则称该数列以A为极限或称数列收敛于A,否则称数列为发散, 极限值 左…...

sourcetree gitee 详细使用

SSH 公钥设置 | Gitee 帮助中心 先配置公钥,输入gitee密码完成验证 gitee仓库创建完成 打开sourcetree 如果你本地有项目(vite )需要 git init 在设置中完成远程仓库的添加 (ssh ,https) 直接提交推送,完成后&#xf…...

应急响应(linux 篇,以centos 7为例)

一、基础命令 1.查看已经登录的用户w 2.查看所有用户最近一次登录:lastlog 3.查看历史上登录的用户还有登录失败的用户 历史上所有登录成功的记录 last /var/log/wtmp 历史上所有登录失败的记录 Lastb /var/log/btmp 4.SSH登录日志 查看所有日志:…...

【Scrapy】Scrapy教程5——第一个Scrapy项目

文章目录 Scrapy目录结构第一个爬虫运行爬虫必要说明start_requests()和start_urls如何关闭allowed_domains的限制通过前几节的学习,我们已经了解了Scrapy的基本操作,下面我们开始第一个项目,我以本人的 网址为例进行爬虫讲解,之所以用我自己的网站,是因为我这个网站本来…...

亲测有效!使用Ollama本地部署DeepSeekR1模型,指定目录安装并实现可视化聊天与接口调用

文章目录 一、引言二、准备工作(Ollama 工具介绍与下载)2.1 Ollama介绍2.2 Ollama安装 三、指定目录安装 DeepSeek R1四、Chatbox 可视化聊天搭建4.1 Chatbox下载安装4.2 关联 DeepSeek R1 与 Chatbox 的步骤 五、使用 Ollama 调用 DeepSeek 接口5.1 请求…...

网络基础 【UDP、TCP】

1.UDP 首先我们学习UDP和TCP协议 要从这三个问题入手 1.报头和有效载荷如何分离、有效载荷如何交付给上一层的协议?2.认识报头3.学习该协议周边的问题 UDP报头 UDP我们先从示意图来讲解,认识报头。 UDP协议首部有16位源端口号,16位目的端…...

SQL知识体系

SQL复习 MySQL SQL介绍 SQL SQL的全拼是什么? SQL全拼:Structured Query Language,也叫结构化查询语言。 SQL92和SQL99有什么区别呢? SQL92和SQL99分别代表了92年和99年颁布的SQL标准。 在 SQL92 中采用(&#xff…...

深入浅出:CUDA是什么,如何利用它进行高效并行计算

在当今这个数据驱动的时代,计算能力的需求日益增加,特别是在深度学习、科学计算和图像处理等领域。为了满足这些需求,NVIDIA推出了CUDA(Compute Unified Device Architecture),这是一种并行计算平台和编程模…...

【ISO 14229-1:2023 UDS诊断(ECU复位0x11服务)测试用例CAPL代码全解析⑩】

ISO 14229-1:2023 UDS诊断【ECU复位0x11服务】_TestCase10 作者:车端域控测试工程师 更新日期:2025年02月18日 关键词:UDS诊断协议、ECU复位服务、0x11服务、ISO 14229-1:2023 TC11-010测试用例 用例ID测试场景验证要点参考条款预期结果TC…...

大语言模型入门

大语言模型入门 1 大语言模型步骤1.1 pre-training 预训练1.1.1 从网上爬数据1.1.2 tokenization1.1.2.1 tokenization using byte pair encoding 1.3 预训练1.3.1 context1.3.2 training1.3.3 输出 1.2 post-training1:SFT监督微调1.2.1 token 1.3 强化学习1.3.1 基…...

【网络安全】零基础入门网络安全劝退指北

作为从16年接触网络安全的小白,谈谈零基础如何入门网络安全,有不对的地方,请多多指教。 这些年最后悔的事情莫过于没有把自己学习的东西积累下来形成一个知识体系。 如何入门 简单了解网络安全 网络安全就是指的确保网络系统中的数据不被别…...

【Go | 从0实现简单分布式缓存】-2:HTTP服务端与一致性哈希

本文目录 一、回顾1.1 复习接口 二、http标准库三、实现HTTP服务端四、一致性哈希 本文为极客兔兔“动手写分布式缓存GeeCache”学习笔记。 一、回顾 昨天已经开发了一部分项目,我们先来看看项目结构。 分布式缓存需要实现节点间通信,建立基于 HTTP 的…...

分享一个使用的音频裁剪chrome扩展-Ringtone Maker

一、插件简介 铃声制作器是一个简单易用的 Chrome 扩展,专门用于制作手机铃声。它支持裁剪音频文件的特定片段,并将其下载为 WAV 格式,方便我们在手机上使用。无论是想从一段长音频中截取精彩部分作为铃声,还是对现有的音频进行个…...

知识拓展:设计模式之装饰器模式

装饰器模式拓展 1. 什么是装饰器模式? 装饰器模式(Decorator Pattern)是一种结构型设计模式,允许向一个现有的对象添加新的功能,同时又不改变其结构。装饰器模式通过创建一个装饰类来包装原始类,从而在不修…...

服务器A到服务器B免密登录

#!/bin/bash # 变量定义 source_host"192.168.42.250" # 源主机 IP target_host"192.168.24.43" # 目标主机 IP target_user"nvidia" # 目标主机的用户名 ssh_port"6666" # SSH 端口号 # 生成 SSH…...

【kafka系列】At Most Once语义

目录 1. At-Most-Once语义的定义 2. Kafka实现At-Most-Once的机制 2.1 生产者端 2.2 消费者端 3. At-Most-Once示例 场景描述 3.1 生产者代码(可能丢失消息) 3.2 消费者代码(可能丢失消息) 4. 典型消息丢失场景分析 场景…...

ESP学习-1(MicroPython VSCode开发环境搭建)

下载ESP8266固件:https://micropython.org/download/ESP8266_GENERIC/win电脑:pip install esptools python.exe -m pip install --upgrade pip esptooo.py --port COM5 erase_flash //清除之前的固件 esptool --port COM5 --baud 115200 write_fla…...

CAS单点登录(第7版)10.多因素身份验证

如有疑问,请看视频:CAS单点登录(第7版) 多因素身份验证 概述 多因素身份验证 (MFA) 多因素身份验证(Multifactor Authentication MFA)是一种安全机制,要求用户提供两种…...

数据库提权总结

Mysql提权 UDF提权是利用MYSQL的自定义函数功能,将MYSQL账号转化为系统system权限 前提: 1.UDF提权条件 (1)Mysql版本大于5.1版本udf.dll文件必须放置于MYSQL安装目录下的lib\plugin文件夹下。 (2)Mysql…...

Docker__持续更新......

Docker 1. 基本知识1.1 为什么有Docker?1.2 Docker架构与容器化 画图解释 画图解释2. 项目实战 1. 基本知识 1.1 为什么有Docker? 用一行命令跨平台安装项目,在不同平台上运行项目。把项目打包分享运行应用。 1.2 Docker架构与容器化 准备机器,在机…...

28、深度学习-自学之路-NLP自然语言处理-做一个完形填空,让机器学习更多的内容程序展示

import sys,random,math from collections import Counter import numpy as npnp.random.seed(1) random.seed(1) f open(reviews.txt) raw_reviews f.readlines() f.close()tokens list(map(lambda x:(x.split(" ")),raw_reviews))#wordcnt Counter() 这行代码的…...

IDEA集成DeepSeek AI助手完整指南

在当今快速发展的软件开发领域,AI辅助编程工具正在成为开发者的重要助手。本文将详细介绍如何在IDEA中集成DeepSeek AI助手,帮助开发者提升编程效率。 一、环境准备 © ivwdcwso (ID: u012172506) 1.1 IDEA版本要求 在开始集成之前,需要确保你的IDEA版本满足要求: …...