设计模式--多例模式(Multition pattern)

news2024/11/24 22:57:26

一、什么是多例模式(Multition pattern)

多例模式(Multition pattern)是单例模式的一种扩展,它属于对象创建类型的设计模式。在多例模式中,一个类可以有多个实例,并且这些实例都是该类本身。因此,这样的类也被称为多例类。

多例模式的特点是:

  1. 多例类可以有多个实例。这意味着你可以根据需求实例化指定数量的对象。
  2. 多例类必须能够自我创建并管理自己的实例池。这意味着在查找对象时,如果找不到,则会创建一个新的对象。
  3. 多例模式实际上就是限制了对象的数量,并且有可能对对象进行重复使用。

多例模式在某些情况下可以替代单例模式,特别是在需要创建多个实例且每个实例的生命周期独立的情况下。多例模式通常用于设计复杂的系统,例如数据库连接、网络通信等。

二、多例模式的现实应用场景

数据库连接是一种常见的需要使用多例模式的应用场景。

在数据库应用中,通常需要为每个客户端请求创建一个数据库连接。然而,创建新的数据库连接是一项开销较大的操作,而且如果每个请求都创建新的连接,会很快耗尽系统的资源。因此,我们通常会使用多例模式来管理数据库连接。

在这种场景下,我们创建一个数据库连接池,该连接池可以预先创建一定数量的数据库连接,并保存在连接池中。当有新的请求需要连接数据库时,系统会先从连接池中获取一个空闲的连接,如果连接池中没有空闲的连接,则等待一段时间或者创建新的连接。当请求结束后,该连接会被放回连接池中,以供其他请求使用。

通过这种方式,我们可以重复利用已有的连接,避免频繁创建和销毁连接,提高了系统的性能和稳定性。同时,连接池的大小也可以根据实际需要进行调整,以满足系统的需求。

这种应用场景符合多例模式的特点,即需要创建多个实例,并且每个实例的生命周期是独立的。通过多例模式,我们可以更好地管理这些实例,并提高系统的效率和性能。

三、多例模式的几种类型

多例模式可以分为两种情况:有上限多例模式和无上限多例模式。

有上限多例模式的特点是:

  1. 多例类可以有多个实例。
  2. 多例类必须自己创建自己的实例,并管理自己的实例,和向外界提供自己的实例。

无上限多例模式的特点是:

  1. 多例类可以有多个实例。
  2. 多例类可以由其他的类创建实例,然后返回。

总之,多例模式是一种创建对象的设计模式,它允许在程序中创建多个对象,并且可以通过某种方式限制对象数量或者允许无限制创建对象。

四、单例模式和多例模式的区别和联系

单例模式和多例模式都是设计模式,但它们之间存在一些关键区别:

  1. 对象创建方式:单例模式:确保只有一个对象被创建,该对象通常被存储在一个静态变量中,并在第一次被需要时创建。多例模式:会创建多个对象,每个请求都会创建一个新的对象,通常通过工厂方法或者构造函数来创建对象。
  2. 对象实例化策略:单例模式:只有一个实例,要么全局访问,要么通过单例类访问。多例模式:对于每个请求都创建一个新的对象,所以每个请求都有自己的对象实例。
  3. 设计目的和原则:单例模式:主要是为了解决实例化问题,避免频繁创建和销毁对象,减少系统开销,主要用于那些只需要一个对象的场景。多例模式:主要解决的是并发问题,即当一个请求改变了对象状态,同时其他请求也在处理这个对象时,会出现问题。

总结来说,单例模式主要是为了节省资源,而多例模式主要是为了解决并发问题。在实际应用中,应根据具体情况选择合适的模式。

五、多例模式的代码样例

以下是一个简单的C++代码示例,演示了多例模式:

#include <iostream>  
#include <list>  
  
class Multiton {  
public:  
    static Multiton* getInstance(int id) {  
        std::list<Multiton*>::iterator it = instances.begin();  
        for (; it != instances.end(); ++it) {  
            if ((*it)->id == id) {  
                return *it;  
            }  
        }  
        // 如果未找到具有指定id的实例,则创建新的实例并返回其指针  
        Multiton* newInstance = new Multiton(id);  
        instances.push_back(newInstance);  
        return newInstance;  
    }  
  
    void doSomething() {  
        std::cout << "Multiton doing something" << std::endl;  
    }  
  
private:  
    static std::list<Multiton*> instances;  
    int id;  
    Multiton(int id) : id(id) {}  
    ~Multiton() {}  
};  
  
std::list<Multiton*> Multiton::instances = std::list<Multiton*>();  
  
int main() {  
    Multiton* m1 = Multiton::getInstance(1);  
    Multiton* m2 = Multiton::getInstance(2);  
    Multiton* m3 = Multiton::getInstance(3);  
  
    m1->doSomething();  
    m2->doSomething();  
    m3->doSomething();  
  
    std::cout << "m1 address: " << m1 << std::endl;  
    std::cout << "m2 address: " << m2 << std::endl;  
    std::cout << "m3 address: " << m3 << std::endl;  
  
    return 0;  
}

在Multiton类中,定义了一个静态成员函数getInstance(int id),该函数用于获取具有指定id的Multiton实例的指针。该函数首先遍历instances列表,查找具有指定id的Multiton实例。如果找到了具有指定id的Multiton实例,则返回该实例的指针。如果没有找到,则说明没有创建具有指定id的Multiton实例,通过new运算符创建了一个新的Multiton实例,并将其指针添加到instances列表中,然后返回该实例的指针。

在Multiton类中,还定义了一个成员函数doSomething(),该函数用于执行一些操作。在main函数中,我们创建了三个Multiton实例m1、m2和m3,并通过调用doSomething()函数来执行一些操作。最后,我们打印了这三个实例的地址。

六、使用多例模式需要注意的问题

使用多例模式需要注意以下几个问题:

  1. 实例数量的限制:多例模式限制了对象的数量,有可能对对象进行重复使用。因此,必须确保限制对象的数量,以避免过多对象造成资源浪费和系统性能下降。
  2. 线程安全问题:多例模式下的对象可能有多个线程同时访问,需要考虑线程安全问题。如果对象包含可变的共享数据,需要采取适当的同步措施来保证线程安全。
  3. 依赖管理:多例模式可能会导致对象之间的依赖关系变得复杂。需要仔细管理对象的依赖关系,以避免出现循环依赖或其他问题。
  4. 资源管理:多例模式可能会导致资源浪费,特别是当对象不再需要时。需要合理管理资源,及时释放不再使用的对象所占用的资源。
  5. 构造函数的安全性:多例模式下的构造函数需要确保安全性,特别是在涉及多个对象之间的依赖关系时。需要仔细设计构造函数,避免出现初始化错误或依赖关系问题。
  6. 单例模式的对比:单例模式和多例模式都是创建对象的设计模式,但它们的应用场景和特点有所不同。需要根据具体需求选择合适的模式,并进行相应的设计和管理。

在这里插入图片描述

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

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

相关文章

APM32F4XX USB OTA

近期在研究USB CDC协议&#xff0c;使用USB Virtual Port Com功能与上位机通讯做了OTA功能。开发平台&#xff1a;MDK529开发硬件&#xff1a;APM32F411首先看下手册Flash分布&#xff0c;Flash总共8个扇区。 接下来进行Flash分区。 扇区 0 和 扇区 1做Boo区。 扇区 2做APP跳…

LeetCode(力扣)98. 验证二叉搜索树Python

LeetCode98. 验证二叉搜索树 题目链接代码 题目链接 https://leetcode.cn/problems/validate-binary-search-tree/ 代码 递归 # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # …

基于RabbitMQ的模拟消息队列之五——虚拟主机设计

文章目录 一、创建VirtualHost类二、初始化三、API1.创建交换机2.删除交换机3.创建队列4.删除队列5.创建绑定6.删除绑定7.发送消息转发规则 8.订阅消息1.消费者管理2.推送消息给消费者 3.添加一个消费者管理ConsumerManager9.确认消息 创建VirtualHost类。 1.串起内存和硬盘的数…

ppt怎么压缩?这里有4个方法

ppt怎么压缩&#xff1f;PPT作为我们常用的文档格式&#xff0c;在演讲、总结汇报以及个人简历等场合中起到重要作用。一份PPT的页数可能从十几页到上百页不等&#xff0c;有些小伙伴为了追求ppt文件的美观度&#xff0c;会在文件中插入大量的高清图片&#xff0c;然而这种操作…

(附源码)使用 javascript 制作网页端 3D 贪吃蛇游戏

3D 网页版贪吃蛇游戏&#xff01;下面来具体讲一下如何实现。 该游戏使用 Hightopo 的 SDK 制作&#xff0c;总共 100 多行代码&#xff0c;没有 WebG L基础的同学们也可很快掌握。 场景初始化 首先&#xff0c;我们对页面进行初始化&#xff0c;包括初始化3D场景&#xff0c;…

护眼灯值不值得买?开学给孩子买什么样的护眼台灯

如果不想家里的孩子年纪小小的就戴着眼镜&#xff0c;从小就容易近视&#xff0c;那么护眼灯的选择就非常重要了&#xff0c;但是市场上那么多品类&#xff0c;价格也参差不齐&#xff0c;到底怎么选呢&#xff1f;大家一定要看完本期内容。为大家推荐五款热门的护眼台灯 一、…

XSS结合CSRF

假设我们获得了目标CMS的源码&#xff0c;搭建了一个相同的网站&#xff0c;我们在自己的网站执行添加用户的操作&#xff0c;并且用bp抓包 如图&#xff0c;这是我们抓到的添加用户的数据包 接下来&#xff0c;我们可以根据数据包构造js代码 <script> xmlhttp new XML…

WEBGL(1):WEBGL介绍

1 WebGL容器&#xff08;坐标系&#xff09; 在2D绘图环境中的坐标系统&#xff0c;默认情况下是与窗口坐标系统相同&#xff0c;它以canvas的左上角为坐标原点&#xff0c;沿x轴向右为正值&#xff0c;沿y轴向下为正值。其中canvas坐标的单位都是 "px"。 在浏览器中…

渗透测试工具ZAP入门教程(4)-设置代理谷歌浏览器

ZAP 代理原理 如下浏览器,拿Chrome为例,Chrome发出的请求都会先经过 ZAP, 然后再由 ZAP 发往服务器.如下图: 设置代理 1. Chrome设置只需要在地址栏输入 chrome://settings 2. 然后在搜索栏输入 代理 然后点击 打开您计算机的代理设置 3. 设置手动代理 端口为什么是 8080 呢?…

【发版公告】Virbox Protector 3.1.3.19051 发版- elf 文件支持导入表保护

深盾安全-软件保护工具 Virbox Protector 3 &#xff08; 3.1.3.19051&#xff09;迎来了版本升级.本次升级支持了 elf 文件导入表保护。 以下是本次 Virbox Protector 发版的主要功能&#xff1a; 新功能 1. ELF格式的程序支持导入表保护(Beta)&#xff1b;&#xff1b; 2…

代码随想录笔记--栈与队列篇

1--用栈实现队列 利用两个栈&#xff0c;一个是输入栈&#xff0c;另一个是输出栈&#xff1b; #include <iostream> #include <stack>class MyQueue { public:MyQueue() {}void push(int x) {in_stk.push(x);}int pop() {if(out_stk.empty()){while(!in_stk.empty…

Apollo领航官送福利啦

⭐简单说两句⭐ 作者&#xff1a;后端小知识 CSDN个人主页&#xff1a;后端小知识 &#x1f50e;GZH&#xff1a;后端小知识 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f388;✨百度apollo介绍 全球智能驾驶产业领跑者 起源 百度…

stable diffusion实践操作-文生图

本文专门开一节写文生图相关的内容&#xff0c;在看之前&#xff0c;可以同步关注&#xff1a; stable diffusion实践操作 正文 1 liblib SD1.5底模 lora(baihuaniang_1.0) 详细信息&#xff1a; 底模&#xff1a;SD 1.5 Lora:baihuaniang_1.0 正向提示词&#xff1a; Best …

ubuntu18.04.6的安装教程

目录 一、下载并安装virtualbox virtualbox7.0.8版本的安装 二、Ubuntu的下载与安装 ubuntu18.04.6操作系统 下载 安装 一、下载并安装virtualbox VirtualBox是功能强大的x86和AMD64/Intel64虚拟化企业和家庭使用的产品。VirtualBox不仅是面向企业客户的功能极其丰富的高…

微信小程序 - 2023年最新版手机号快捷登录详细教程

前言 最近开发公司手机快捷登录的功能&#xff0c;花费了不少时间&#xff0c;这里附上详细教程。 这里以海底捞小程序的图片为例&#xff0c;如有侵权请联系小编删除。 代码如下 <button open-type"getPhoneNumber" getphonenumber"getPhoneNumber"…

自动驾驶——【规划】记忆泊车特殊学习路径拟合

1.Back ground 如上图&#xff0c;SLAM学习路线Start到End路径&#xff0c;其中曲线SDAB为D档位学习路径&#xff0c;曲线BC为R学习路径&#xff0c;曲线AE为前进档D档学习路径。 为了使其使用记忆泊车时&#xff0c;其驾驶员体验感好&#xff0c;需去除R档倒车部分轨迹&#x…

【STM32教程】第三章 使用OLED屏作为调试工具

案例代码及相关资料下载链接&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1hsIibEmsB91xFclJd-YTYA?pwdjauj 提取码&#xff1a;jauj 1 OLED调试工具 1.1对程序调试的认识与OLED简介 本章节只需要知道怎么调用封装好的驱动函数&#xff0c;用OLED屏幕来做调…

高效使用WMS仓储管理系统,需要关注这八个点

在现代供应链中&#xff0c;WMS仓储管理系统扮演着至关重要的角色。然而&#xff0c;随着供应链需求的不断增长和变化&#xff0c;实施WMS仓储管理系统面临着越来越多的挑战和要求。本文将探讨使用WMS仓储管理系统需要考虑的8大因素&#xff0c;以适应现代供应链的需求。 一、W…

我们把“高血压”小游戏真正做到了不用下载,点击即玩!!!

相信大家经常在短视频网站上刷到各种“高血压“小游戏吧&#xff0c;当你按捺不住点击&#xff0c;却发现手机上多了一大堆“流氓软件”的时候&#xff0c;血压就更高了。 但是&#xff01; 今天&#xff01; 我们把“虚假广告”做成了真实的游戏&#xff0c;并且可以轻松部署到…

在Linux服务器部署多台nginx

升级版2.0关于如何在linux服务器上布置多台nginx&#xff0c;之前吃了点苦头&#xff0c;特写文章避免重蹈覆辙。 文章目录 前言一、下载环境依赖二、安装nginx1.创建放置nginx的文件2.上传解压压缩包3.安装nginx&#xff08;关键步&#xff09; 三、启动nginx四、验证nginx是否…