不得不说的结构型模式-享元模式

news2024/12/25 12:30:05

 

目录

享元模式(Flyweight Pattern):

下面是一个简单的C++代码案例

下面是面试中可能遇到的问题:


享元模式(Flyweight Pattern):

是一种结构型模式,它通过共享对象来减少系统中对象的数量,从而降低系统的内存占用和运行开销。

在享元模式中,通过将对象的内部状态和外部状态分离,将一些共享内部状态的对象设计成享元,即可在系统中共享这些对象,而外部状态则由客户端在使用时传入。这样就可以减少系统中需要创建的对象数量,从而降低内存占用和运行开销。

下面是一个简单的C++代码案例

以图书馆借阅为例,演示如何使用享元模式。

首先定义一个抽象图书类 Book,其中包含了图书的基本信息,如书名、作者、出版社等。

 

class Book {
public:
    virtual void showInfo(const std::string& borrower) = 0;
};

然后定义一个具体的图书类 Novel,它继承自抽象图书类,并实现了 showInfo 方法。

class Novel : public Book {
public:
    Novel(const std::string& title, const std::string& author, const std::string& publisher) :
        title_(title), author_(author), publisher_(publisher) {}

    virtual void showInfo(const std::string& borrower) override {
        std::cout << "《" << title_ << "》是" << author_ << "的作品,出版社是" << publisher_ << "。借阅人:" << borrower << std::endl;
    }

private:
    std::string title_;
    std::string author_;
    std::string publisher_;
};

接下来定义一个享元工厂类 BookFactory,它负责创建和管理图书对象,同时提供一个借阅方法 borrowBook,该方法接收借阅人的姓名和图书的名称,根据图书名称查找对应的图书对象,将借阅人的姓名作为外部状态传入图书对象的 showInfo 方法中。

class BookFactory {
public:
    std::shared_ptr<Book> getBook(const std::string& title) {
        auto iter = books_.find(title);
        if (iter != books_.end()) {
            return iter->second;
        } else {
            auto book = std::make_shared<Novel>(title, "unknown", "unknown");
            books_[title] = book;
            return book;
        }
    }

    void borrowBook(const std::string& borrower, const std::string& title) {
        auto book = getBook(title);
        book->showInfo(borrower);
    }

private:
    std::unordered_map<std::string, std::shared_ptr<Book>> books_;
};

最后,在 main 函数中使用 BookFactory 创建和管理图书对象,借阅图书。

int main() {
    BookFactory bookFactory;

    bookFactory.borrowBook("张三", "红楼梦");
    bookFactory.borrowBook("李四", "红楼梦");
    bookFactory.borrowBook("王五", "水浒传");
    bookFactory.borrowBook("赵六", "水浒传");

在上面的代码中,BookFactory 维护了一个图书对象的映射表 books_,其中 key 为图书名称,value 为对应的图书对象。

在 borrowBook 方法中,首先调用 getBook 方法查找对应的图书对象。如果该对象已经存在于映射表中,则直接返回该对象;否则创建一个新的图书对象,并将其添加到映射表中。

然后将借阅人的姓名和图书名称作为外部状态传入图书对象的 showInfo 方法中,该方法根据内部状态(图书的基本信息)和外部状态(借阅人的姓名)生成图书的详细信息,打印出来。

通过使用享元模式,BookFactory 可以共享已经存在的图书对象,避免重复创建对象,从而降低系统内存占用和运行开销。

下面是面试中可能遇到的问题:

问题1:请简单介绍一下享元模式的定义和特点?

答案1:享元模式是一种结构型设计模式,它通过共享对象来减少系统中对象的数量,从而降低系统的内存占用和运行开销。在享元模式中,通过将对象的内部状态和外部状态分离,将一些共享内部状态的对象设计成享元,即可在系统中共享这些对象,而外部状态则由客户端在使用时传入。特点包括:

  1. 降低系统内存占用和运行开销,特别适用于需要大量创建相似对象的场景。
  2. 将对象的内部状态和外部状态分离,提高系统的灵活性和可扩展性。
  3. 享元对象可以被多个客户端共享,但是必须是不可变的,即不能被修改。

问题2:请举例说明什么场景适合使用享元模式?

答案2:享元模式适合在以下场景中使用:

  1. 当系统需要大量创建相似的对象,且这些对象的内部状态可以共享时,如字体、颜色、图片等。
  2. 当系统需要缓存大量对象以提高性能时,如线程池、连接池等。
  3. 当对象的创建和销毁开销较大,但是需要频繁使用时,如数据库连接等。

问题3:请简单描述一下享元模式的实现方式?

答案3:享元模式的实现方式包括以下几个步骤:

  1. 定义享元类,将对象的内部状态和外部状态分离。
  2. 定义享元工厂类,用于创建和管理享元对象。
  3. 在享元工厂类中维护一个对象池,用于缓存已经创建的享元对象。
  4. 在客户端使用享元对象时,需要将外部状态传入享元对象的方法中。

问题4:请简述一下享元模式的优缺点?

答案4:享元模式的优点包括:

  1. 可以降低系统内存占用和运行开销。
  2. 提高系统的灵活性和可扩展性。
  3. 可以缓存对象,提高系统性能。

缺点包括:

  1. 需要将对象的内部状态和外部状态分离,增加系统的复杂度。
  2. 共享对象可能会引入线程安全问题。
  3. 如果对象池过大,会增加系统的管理开销。

问题5:请简单描述一下享元模式和单例模式的区别?

答案5:享元模式和单例模式都是设计模式中比较常见的模式,但是它们的目的和使用场景不同。

享元模式的目的是通过共享对象来减少系统中对象的数量,从而降低系统的内存占用和运行开销,适用于需要大量创建相似对象的场景。而单例模式的目的是保证一个类只有一个实例,适用于需要全局访问一个唯一的对象的场景。

此外,享元模式和单例模式的实现方式也有一些不同。享元模式通常需要设计一个享元工厂类来管理对象池和对象的创建和获取,而单例模式通常使用静态方法或全局变量来保证只有一个实例。

问题6:请举例说明享元模式的应用?

答案6:享元模式可以应用于以下场景:

  1. 用于实现字体、颜色等的共享。
  2. 用于实现线程池、连接池等的对象池。
  3. 用于实现大型网站中的页面缓存,将页面中的公共部分缓存为共享对象,减少页面的加载时间和网络带宽的占用。

问题7:请问你在实际项目中有使用过享元模式吗?如果有,请简单描述一下你的使用场景和实现方式?

答案7:在我的一个项目中,我们需要实现一个图形化界面,其中包含大量的按钮和标签等控件。由于控件数量较多,我们考虑使用享元模式来共享相同类型的控件对象,从而降低系统内存占用和运行开销。

我们定义了一个控件类和一个控件工厂类。在控件工厂类中,我们维护了一个对象池,用于缓存已经创建的控件对象。当客户端需要使用一个控件时,我们先在对象池中查找是否存在相同类型的控件对象,如果存在,则直接返回该对象;否则,创建一个新的控件对象,并将其添加到对象池中。

通过使用享元模式,我们成功地减少了系统内存占用和运行开销,并提高了系统的性能和响应速度。

总的来说,享元模式通过共享对象来降低系统内存占用和运行开销,特别适用于需要大量创建相似对象的场景。在实现时,需要将对象的内部状态和外部状态分离,将共享内部状态的对象设计成享元,提供一个工厂类来创建和管理对象,并在使用时传入外部状态。

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

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

相关文章

第四范式发布「式说」大模型,以生成式AI重构企业软件(AIGS)

4月26日&#xff0c;第四范式首次向公众展示其大模型产品「式说3.0」&#xff0c;并首次提出AIGS战略&#xff08;AI-Generated Software&#xff09;&#xff1a;以生成式AI重构企业软件。式说将定位为基于多模态大模型的新型开发平台&#xff0c;提升企业软件的体验和开发效率…

湿法冶金铼提取工艺

湿法冶金 通过溶液分离金属的技术 湿法冶金是利用浸出剂在一定温度压力下与矿石接触&#xff0c;把矿石中有用的金属溶解后再从溶液中回收有价金属的一种工艺&#xff0c;因为其过程大都是在水溶液中进行&#xff0c;所以又被称为“水法冶金”。 01 湿法冶金工艺特点及工艺流…

AI智能课程:第五讲chatGPT搞定APP小程序

内容总结 作业 目录 APP&小程序测试初识 ### APP&小程序测试的区别&#xff1f; 设计APP&小程序功能测试用例 设计APP&小程序功能测试用例–继续优化 设计APP&小程序测试用例-中断场景 设计小程序测试用例–补充小程序功能专项 APP&小程序兼容性测试…

Raft 共识算法4-选举限制

Raft 共识算法4-选举限制 Raft算法中译版地址&#xff1a;https://object.redisant.com/doc/raft%E4%B8%AD%E8%AF%91%E7%89%88-2023%E5%B9%B44%E6%9C%8823%E6%97%A5.pdf 英原论文地址&#xff1a;https://raft.github.io/raft.pdf Etcd Assistant 是一款 etcd 可视化管理软件&a…

大数据Doris(四):FE部署及启动

文章目录 FE部署及启动 一、创建doris 部署目录 二、上传安装包并解压

Monaco Editor编辑器教程(二八):Monaco 与 VS Code 两个项目的联系与异同点

前言 很多人知道前端代码编辑Monaco Editor 与VS Code 有关系,但却不清楚其中的细节,本篇文章就带大家了解一下两者的关系和异同点。 表面对比 首先,这两个项目都是来自微软,其中VS Code 项目Github 144K star,是基于CS架构,客户端-服务端架构。主要的技术栈是 electo…

你不知道的自动装箱和拆箱

“改天是明天&#xff0c;下次是每一次&#xff0c;以后是以后的每一天” 自动装箱和拆箱 装箱就是自动将基本数据类型转换为包装器类型(int–>Integer);调用方法:Integer的valueOf(int) 方法 拆箱就是自动将包装器类型转换为基本数据类型(Integer–>int);调用方法:I…

骨传导蓝牙耳机哪款好,分享几款性能比较高的骨传导耳机

骨传导耳机是一种新型的耳机&#xff0c;它将声音转化为不同频率的机械振动&#xff0c;通过人的颅骨、骨迷路、内耳淋巴液、螺旋器、听觉中枢来传递声波。不需要通过耳道&#xff0c;是一种耳挂式的无线耳机。 骨传导耳机与普通耳机相比&#xff0c;最大的优势是不需要入耳&am…

VasDolly实现多渠道打包

目录 一、添加对VasDolly Plugin的依赖 二、 引用VasDolly Plugin 三、添加对VasDolly helper类库的依赖 四、根目录新建文件添加渠道列表 五、主App工程的build.gradle中配置channel 六、根据已有基础包重新生成多渠道包 官方地址&#xff1a; GitHub - Tencent/VasDol…

【21】linux进阶——grep命令搜索查找

大家好&#xff0c;这里是天亮之前ict&#xff0c;本人网络工程大三在读小学生&#xff0c;拥有锐捷的ie和红帽的ce认证。每天更新一个linux进阶的小知识&#xff0c;希望能提高自己的技术的同时&#xff0c;也可以帮助到大家 另外其它专栏请关注&#xff1a; 锐捷数通实验&…

【1048. 最长字符串链】

来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 描述&#xff1a; 给出一个单词数组 words &#xff0c;其中每个单词都由小写英文字母组成。 如果我们可以 不改变其他字符的顺序 &#xff0c;在 wordA 的任何地方添加 恰好一个 字母使其变成 wordB &#xff0c;那么…

【AI】Python 安装时启用长路径支持

文章目录 场景&#xff1a;解释&#xff1a;关于文件长路径&#xff1a;计算方法&#xff1a; 场景&#xff1a; Python 安装时&#xff0c;会出现 Disable path length limit 的提示。 解释&#xff1a; 在 Windows 操作系统中&#xff0c;文件路径的长度是有限制的。在早期…

连续Hopfield神经网络的优化——旅行商问题优化计算

连续Hopfield神经网络 连续Hopfield神经网络&#xff08;Continuous Hopfield Network, CHN&#xff09;是一种基于能量最小化原理的神经网络模型&#xff0c;与离散Hopfield网络相比&#xff0c;它的状态是连续的&#xff0c;典型地采用实数值或者概率分布。在优化连续Hopfie…

各大外卖平台占据共享经济市场主要份额,占比近50%

哈喽大家好&#xff0c;随着大量互联网用户和移动支付的普及、大量用户通过共享平台将闲置资源和服务与需求方进行匹配&#xff0c;实现了资源的高效利用和消费者福利的提升。在全球化驱动的新型消费需求以及政策支持下&#xff0c;共享经济正在向更加成熟和规范化的方向发展。…

【生态环境保护】绿水青山就是金山银山——生态环保篇

环保是一个持续性的话题&#xff0c;不仅仅是在国内&#xff0c;整个世界都是一个命运共同体从城市垃圾分类&#xff0c;到农村/村镇污水治理&#xff0c;城乡一体化和因地制宜的实施方式&#xff0c;是我们一直在探索的。 从余村到全国&#xff0c;从中国到世界&#xff0c;“…

网络安全合规-数据安全治理体系建设

一、数据安全治理体系建设思路&#xff1a; 一级文档。由决策层认可、面向组织的数据安全方针&#xff0c;通常应包括组织数据安全工作的总体目标、基本原则、数据安全决策机构设置与职责划分等。 二级文档。根据数据安全方针的要求&#xff0c;对组织数据安全工作各关键领域的…

黑客攻击的心理学:了解黑客的行为背后隐藏的心理因素

第一章&#xff1a;引言 在当今数字时代&#xff0c;网络已经成为人们交流、信息传递、商业活动的主要方式之一。但随之而来的是网络安全问题的不断浮现&#xff0c;其中最为突出的就是黑客攻击。黑客攻击不仅仅是技术问题&#xff0c;还涉及到心理学、社会学等多方面因素。了…

LoRA 理解

LLM的参数量对于时间和显存要求都带来很大的挑战。现存的两种显著范式: 增加adapter&#xff1a;主要问题在于推理时带来的额外计算量和延迟。优化prompt&#xff1a; 前缀微调(Prefix Tuning)较难优化&#xff0c;而且随着参数量增长性能并非单调变化。 那有什么方法可以 解…

一篇简单的文章带你玩转SpringBoot 之定时任务详解

序言 使用SpringBoot创建定时任务非常简单&#xff0c;目前主要有以下三种创建方式&#xff1a; 一、基于注解(Scheduled)二、基于接口&#xff08;SchedulingConfigurer&#xff09; 前者相信大家都很熟悉&#xff0c;但是实际使用中我们往往想从数据库中读取指定时间来动态…

Linux网络编程TCP连接的建立和终止

文章目录 前言一、TCP的三路握手二、TCP连接终止总结 前言 本篇文章将讲解TCP的连接的建立和终止&#xff0c;主要就是讲解TCP的三路握手和TCP连接断开内部发生的一些机制和事件。 一、TCP的三路握手 TCP三路握手所交换的三个分节&#xff1a; (1)服务器必须准备好接受外来…