《设计模式的艺术》笔记 - 享元模式

介绍

        享元模式运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻量级模式,是一种对象结构型模式。

实现

myclass.h

//
// Created by yuwp on 2024/1/12.
//#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H#include <iostream>
#include <unordered_map>class Flyweight {   // 享元抽象类
public:Flyweight(const std::string &in);virtual void operation(const std::string &out) = 0;const std::string &getMIn() const;private:std::string m_in;
};class ConcreteFlyweight : public Flyweight {    // 具体享元类
public:ConcreteFlyweight(const std::string &in);void operation(const std::string &out) override;
};class FlyweightFactory {    // 配合工厂模式使用享元工厂类
public:~FlyweightFactory();Flyweight *getFlyweight(const std::string &key);
private:std::unordered_map<std::string, Flyweight *> m_flyweights;
};#endif //DESIGNPATTERNS_MYCLASS_H

myclass.cpp

//
// Created by yuwp on 2024/1/12.
//#include "myclass.h"Flyweight::Flyweight(const std::string &in) {m_in = in;
}const std::string &Flyweight::getMIn() const {return m_in;
}ConcreteFlyweight::ConcreteFlyweight(const std::string &in) : Flyweight(in) {}void ConcreteFlyweight::operation(const std::string &out) {std::cout<< "内部状态: " << getMIn() << ", 外部状态: " << out << std::endl;
}FlyweightFactory::~FlyweightFactory() {for (auto it : m_flyweights) {if (it.second) {delete it.second;}}
}Flyweight* FlyweightFactory::getFlyweight(const std::string &key) {auto it = m_flyweights.find(key);if (it != m_flyweights.end()) {return it->second;} else {Flyweight *flyweight = new ConcreteFlyweight(key);m_flyweights.insert(std::make_pair(key, flyweight));return flyweight;}
}

main.cpp

#include <iostream>
#include <mutex>
#include "myclass.h"int main() {FlyweightFactory *factory = new FlyweightFactory();auto fly1 = factory->getFlyweight("a");auto fly2 = factory->getFlyweight("b");auto fly3 = factory->getFlyweight("a");fly1->operation("1");fly2->operation("2");fly3->operation("3");delete factory;return 0;
}

总结

优点

        1. 可以极大减少内存中对象的数量,使得相同或相似对象在内存中只保存一份,从而可以节约系统资源,提高系统性能。

        2. 享元模式的外部状态相对独立,而且不会影响其内部状态,从而使得享元对象可以在不同的环境中被共享。

缺点

        1. 享元模式需要分离出内部状态和外部状态,从而使得系统变得复杂,这使得程序的逻辑复杂化。

        2. 为了使对象可以共享,享元模式需要将享元对象的部分状态外部化,而读取外部状态将使得运行时间变长。

适用场景

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

        2. 对象的大部分状态都可以外部化,可以将这些外部状态传入对象中。

        3. 在使用享元模式时需要维护一个存储享元对象的享元池,而这需要耗费一定的系统资源。因此,在需要多次重复使用同一享元对象时才值得使用享元模式。

练习

myclass.h

//
// Created by yuwp on 2024/1/12.
//#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H#include <iostream>
#include <unordered_map>class Flyweight {   // 享元抽象类
public:Flyweight(const std::string &in);virtual void display(const std::string &out) = 0;const std::string &getMIn() const;private:std::string m_in;
};class PictureFlyweight : public Flyweight {    // 具体享元类
public:PictureFlyweight(const std::string &in);void display(const std::string &out) override;
};class AnimationFlyweight : public Flyweight {    // 具体享元类
public:AnimationFlyweight(const std::string &in);void display(const std::string &out) override;
};class VideoFlyweight : public Flyweight {    // 具体享元类
public:VideoFlyweight(const std::string &in);void display(const std::string &out) override;
};class FlyweightFactory {    // 配合工厂模式使用享元工厂类
public:~FlyweightFactory();Flyweight *getFlyweight(const std::string &key);static FlyweightFactory *getInstance();
private:FlyweightFactory();std::unordered_map<std::string, Flyweight *> m_flyweights;
};#endif //DESIGNPATTERNS_MYCLASS_H

myclass.cpp

//
// Created by yuwp on 2024/1/12.
//#include "myclass.h"Flyweight::Flyweight(const std::string &in) {m_in = in;
}const std::string &Flyweight::getMIn() const {return m_in;
}PictureFlyweight::PictureFlyweight(const std::string &in) : Flyweight(in) {}void PictureFlyweight::display(const std::string &out) {std::cout << out << ", " << getMIn() << std::endl;
}AnimationFlyweight::AnimationFlyweight(const std::string &in) : Flyweight(in) {}void AnimationFlyweight::display(const std::string &out) {std::cout << out << ", " << getMIn() << std::endl;
}VideoFlyweight::VideoFlyweight(const std::string &in) : Flyweight(in) {}void VideoFlyweight::display(const std::string &out) {std::cout << out << ", " << getMIn() << std::endl;
}FlyweightFactory::FlyweightFactory() {}FlyweightFactory* FlyweightFactory::getInstance() {static FlyweightFactory *factory = new FlyweightFactory();return factory;
}FlyweightFactory::~FlyweightFactory() {for (auto it : m_flyweights) {if (it.second) {delete it.second;}}
}Flyweight* FlyweightFactory::getFlyweight(const std::string &key) {auto it = m_flyweights.find(key);if (it != m_flyweights.end()) {return it->second;} else {Flyweight *flyweight = nullptr;if (key == "图片") {flyweight = new PictureFlyweight(key);} else if (key == "动画") {flyweight = new AnimationFlyweight(key);} else if (key == "视频") {flyweight = new VideoFlyweight(key);}m_flyweights.insert(std::make_pair(key, flyweight));return flyweight;}
}

main.cpp

#include <iostream>
#include <mutex>
#include "myclass.h"int main() {FlyweightFactory *factory = FlyweightFactory::getInstance();factory->getFlyweight("图片")->display("1");factory->getFlyweight("动画")->display("2");factory->getFlyweight("视频")->display("3");factory->getFlyweight("图片")->display("4");return 0;
}

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

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

相关文章

洛谷P1161 开灯

这倒也是水题&#xff0c;我们可以建立一个数组&#xff0c;数组的下标就是编号&#xff0c;我们要注意的是浮点数乘法的结果要转化成整数&#xff0c;才能当做下标&#xff0c;因为题目给的是整数编号。 # include <stdio.h> int main() {int a[1000000] { 0 }, n, t,…

【linux】linux系统安装与更新软件

前言 linux系统安装软件有许多的方式&#xff0c;本文列举的是类似于windows从应用商店安装软件的方法。也是最常用最省事的方法。 但是呢linux系统是有许多发行版本的&#xff0c;不同版本的命令不同&#xff0c;但语法基本是一模一样。 概念插入 windows系统中&#xff0c…

IPv6自动隧道---6to4隧道

IPv6 over IPv4自动隧道特点 由于IPv4兼容IPv6隧道要求每一个主机都要有一个合法的IP地址,而且通讯的主机要支持双栈、支持IPv4兼容IPv6隧道,不适合大面积部署。目前该技术已经被6to4隧道所代替。 6to4隧道 集手动隧道和自动隧道的优点于一身,提出6to4的目的是为IPv4网络…

Linux如何创建文件

使用touch命令&#xff1a;使用touch命令可以创建一个新文件&#xff0c;如果文件已经存在&#xff0c;则只更新其访问时间和修改时间。例如&#xff0c;要创建一个名为test.txt的文件&#xff0c;请在终端中输入以下命令&#xff1a; touch test.txt使用echo命令&#xff1a;使…

【Spring源码分析】从源码角度去熟悉依赖注入(一)

从源码角度去熟悉依赖注入 一、全局出发引出各种依赖注入策略二、Autowired依赖注入源码分析属性注入源码分析&#xff08;AutowiredFieldElement.inject&#xff09;方法注入源码分析&#xff08;AutowiredMethodElement.inject&#xff09;流程图 其实在上篇阐述非懒加载单例…

UE5 独立程序的网络TCP/UDP服务器与客户端基础流程

引擎源码版&#xff0c;复制\Engine\Source\Programs\路径下的BlankProgram空项目示例。 重命名BlankProgram&#xff0c;例如CustomTcpProgram&#xff0c;并修改项目名称。 修改.Build.cs内容 修改Target.cs内容 修改Private文件夹内.h.cpp文件名并修改.cpp内容 刷新引擎 …

模拟StopWatch改写的一款耗时调试工具

StopWatch在单个文件的单个方法中确时还蛮好用的&#xff0c;但跨多个文件&#xff0c;多个方法的同一线程内调试就有明显的不舒服。一是要建立ThreadLocal共享StopWatch的实例。二是StopWatch的start和stop必须形成闭合。在方法嵌套的场景。比如要查看大方法执行时间&#xff…

性能测试中的基准测试

在性能测试中有一种测试类型叫做基准测试。这篇文章&#xff0c;就聊聊关于基准测试的一些事儿。 1、定义 通过设计合理的测试方法&#xff0c;选用合适的测试工具和被测系统&#xff0c;实现对某个特定目标场景的某项性能指标进行定量的和可对比的测试。 2、特质 ①、可重…

ChatGPT 如何解决 “Something went wrong. lf this issue persists ….” 错误

Something went wrong. If this issue persists please contact us through our help center at help.openai.com. ChatGPT经常用着用着就出现 “Something went wrong” 错误&#xff0c;不管是普通账号还是Plus账号&#xff0c;不管是切换到哪个节点&#xff0c;没聊两次就报…

Unity3D代码混淆方案详解

背景 Unity引擎使用Mono运行时&#xff0c;而C#语言易受反编译影响&#xff0c;存在代码泄露风险。本文通过《QQ乐团》项目实践&#xff0c;提出一种适用于Unity引擎的代码混淆方案&#xff0c;以保护代码逻辑。 引言 在Unity引擎下&#xff0c;为了防止代码被轻易反编译&a…

linux 访问共享文件夹

在Linux中&#xff0c;可以使用mount命令来访问共享文件夹。 首先&#xff0c;确保已经安装了smbclient工具包&#xff08;如果没有安装的话&#xff09;&#xff1a; sudo yum install samba 创建本地目录作为共享文件夹的挂载点&#xff1a; mkdir /mnt/shared_folder 使…

Vue created()和 activated()区别和作用调用顺序

目录 作用 区别 举个例子 调用顺序 作用 简单说都是用于页面初始化&#xff0c;土话说一进来页面&#xff0c;去进行数据加载或调用方法的 区别 首先activated 钩子只适用于被 <keep-alive> 包裹的组件。对于不被 <keep-alive> 包裹的组件&#xff0c;activate…

CSS实现的 Loading 效果

方式一、纯CSS实现 代码&#xff1a;根据需要复制 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>CSS Animation Library for Developers and Ninjas</title><style>/* ---------------…

RV1106移植心得

参考&#xff1a;SDK 环境部署 | LUCKFOX WIKI 在网上买了个开发板。很便宜。 1、下载源码&#xff1a; git clone https://gitee.com/LuckfoxTECH/luckfox-pico.git cd luckfox-pico git submodule update --init 2.查看如何编译&#xff1a; 在根目录有个readme_cn.txt文…

2024年甘肃省职业院校技能大赛信息安全管理与评估 样题三 模块一

竞赛需要完成三个阶段的任务&#xff0c;分别完成三个模块&#xff0c;总分共计 1000分。三个模块内容和分值分别是&#xff1a; 1.第一阶段&#xff1a;模块一 网络平台搭建与设备安全防护&#xff08;180 分钟&#xff0c;300 分&#xff09;。 2.第二阶段&#xff1a;模块二…

ILI2130触控IC驱动

概述 ili2130触控网上有关的介绍很少&#xff0c;官网也没有有用的东西&#xff0c;所以记录一其驱动&#xff08;MCU驱动&#xff09;。此外ILI2520, ILI2521, ILI2322, ILI2323, ILI2316, ILI2326, ILI2130, ILI2131, ILI2132这几款触控IC使用的是同一个用户指导手册&#x…

吃瓜教程Task1:概览西瓜书+南瓜书第1、2章

由于本人之前已经学习过西瓜书&#xff0c;本次学习主要是对以往知识的查漏补缺&#xff0c;因此本博客记录了在学习西瓜书中容易混淆的点以及学习过程中的难点。更多学习内容可以参考下面的链接&#xff1a; 南瓜书的地址&#xff1a;https://github.com/datawhalechina/pumpk…

zabbix实验

目录 一、zabbix 自动发现与自动注册 1、zabbix 自动发现 ①关闭防火墙和安全机制 ②在服务端和客户端上配置 hosts 解析 ③在 Web 页面配置自动发现 2、zabbix 自动注册 ①环境准备 ②在服务端和客户端上配置 hosts 解析 ③修改 zabbix-agent2 配置文件 ④在 Web 页…

从静态到动态:视频美颜SDK在短视频平台的应用全面解析

为了在短视频平台上实现更出色的美颜效果&#xff0c;开发者们通常会借助视频美颜SDK。本文将深入探讨视频美颜SDK在短视频平台上的应用&#xff0c;从技术原理、性能优化到用户体验等方面进行全面解析。 一、技术原理与算法演进 视频美颜SDK的核心在于其算法&#xff0c;而…

PHP 支付宝(单笔转账到银行账户接口)

alipay.fund.trans.tobank.transfer(单笔转账到银行账户接口) 小程序文档 - 支付宝文档中心 一、下载支付宝SDK&#xff0c;现有版本v1、v2、v3 https://github.com/alipay/alipay-sdk-php-all github 慢的话&#xff0c;DNS 直达即可 140.82.112.3 github.com 【host文…