设计模式——单例模式和工厂模式

单例设计模式和工厂设计模式 阅读详情

本文转载于:https://www.jianshu.com/p/c579d9ba80be

1、单例模式

    确保某一个对象只有一个实例,而且自行实例化并向整个程序提供这个实例。单例模式为什么能保证只有一个实例存在,原因是在于它的构造函数是私有的,你不能去new 它,该单例类里面已经实例化好了一个了,并且是static的,并提供一个获取该实例的方法。客户端只能通过该方法获取这个已经实例化好了的,这样就保证了只有一个实例存在!

(1)优点

  • 由于单例模式在内存中只有一个实例,减少了内存开支,特别是一个对象需要频繁地创建、销毁时,而且创建或销毁时性能又无法优化,单例模式的优势就非常明显。
  • 减少了系统的性能开销,当一个对象的产生需要比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存的方式来解决。
  • 避免对资源的多重占用。如避免对同一个资源文件的同时写操作。
  • 单例模式可以在系统设置全局的访问点,优化和共享资源访问。

(2)缺点

  • 单例模式一般没有接口,扩展困难。
  • 不利于测试。

(3)使用场景

  • 要求生成唯一序列号的环境。
  • 在整个项目中需要一个共享访问点或共享数据。
  • 创建一个对象需要消耗的资源过多,如要访问IO和数据库等资源。
  • 需要定义大量的静态常量和静态方法的环境。

(4)实现

  1)懒汉实现方法,即实例化在对象首次被访问时进行。可以使用类的私有静态指针变量指向类的唯一实例,并用一个公有的静态方法获取该实例。同时需将默认构造函数声明为private,防止用户调用默认构造函数创建对象。

class CSingleton
{
private:
    CSingleton(){};
    static CSingleton* m_pInstance;
    class CGarbo
    {
    public:
        ~CGarbo(){
            if(CSingleton::m_pInstance != NULL)
            delete CSingleton::m_pInstance;
        }
    };
    static CGarbo garbo;
public:
    static CSingleton* GetInstance(){
        if (m_Instance == NULL )
        {
            Lock(); 
            if (m_Instance == NULL )
            {
                m_Instance = new Singleton ();
            }
            UnLock(); 
        }
        return m_pInstance;
    }
};

    类CGarbo被定义为CSingleton的私有内嵌类,以防该类被在其他地方滥用。程序运行结束时,系统会调用CSingleton的静态成员Garbo的析构函数,该析构函数会删除单例的唯一实例。

  2)饿汉实现方法:在程序开始时就自行创建实例。如果说懒汉式是“时间换空间”,那么饿汉式就是“空间换时间”,因为一开始就创建了实例,所以每次用到的之后直接返回就好了。

class CSingleton
{
private:
    CSingleton(){};
    static CSingleton* m_pInstance;
    class CGarbo
    {
    public:
        ~CGarbo(){
            if(CSingleton::m_pInstance != NULL)
            delete CSingleton::m_pInstance;
        }
    };
    static CGarbo garbo;
public:
    static CSingleton* GetInstance(){
        return m_pInstance;
    }
};
CSingleton *CSingleton::m_pInstance = new CSingleton();

2、工厂模式

    这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

                       

意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个产品类,工厂模式使其创建过程延迟到子类进行。

主要解决:主要解决接口选择的问题。

何时使用:我们明确地计划不同条件下创建不同实例时。

如何解决:让其子类实现工厂接口,返回的也是一个抽象的产品。

优点:

  • 一个调用者想创建一个对象,只要知道其名称就可以了。
  • 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
  • 屏蔽产品的具体实现,调用者只关心产品的接口。

缺点:

  •  每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

使用场景:

  • 日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。
  • 数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。
  • 设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口。

注意事项:
    作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

实现

(1)简单工厂模式

#include <iostream>
using namespace std;

class Shape
{
public:
    virtual void draw()=0;
};

class Square : public Shape
{
public:
    void draw(){
        cout<<"This is a square."<<endl;
    }
};

class Rectangle : public Shape
{
public:
    void draw(){
        cout<<"This is a rectangle."<<endl;
    }
};

class Circle :public Shape
{
public:
    void draw(){
        cout<<"This is a circle"<<endl;
    }
};

class SimpleFactory
{
public:
    typedef enum ShapeType
    {
        ShapeSquare,
        ShapeRectangle,
        ShapeCircle
    }SHAPETYPE;
    Shape* getShape(SHAPETYPE type)
    {
        switch(type)
        {
        case ShapeSquare:
            return new Square();
        case ShapeRectangle:
            return new Rectangle();
        case ShapeCircle:
            return new Circle();
        default:
            return NULL;
        }
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    SimpleFactory* myFactory = new SimpleFactory();
    Shape* myShape = myFactory->getShape(SimpleFactory::ShapeCircle);
    myShape->draw();
    delete myShape;
    myShape = NULL;
    delete myFactory;
}

(2)工厂方法模式
    拥有几个工厂,都派生自同一抽象工厂类,可以生产不同的产品。

class AbstractProduct
{
public:
    virtual void operation()=0;
};

class ProductA : public AbstractProduct
{
public:
    virtual void operation(){
        cout<<"This is A!"<<endl;
    }
};

class ProductB : public AbstractProduct
{
public:
    virtual void operation(){
        cout<<"This is B!"<<endl;
    }
};

class AbstractFactory
{
public:
    virtual AbstractProduct* createProduct()=0;
};

class FactoryA : public AbstractFactory
{
public:
    AbstractProduct* createProduct(){
        return new ProductA();
    }
};

class FactoryB : public AbstractFactory
{
public:
    AbstractProduct* createProduct(){
        return new ProductB();
    }
};

int main()
{
    AbstractFactory* myFactory = new FactoryA();
    AbstractProduct* myProduct = myFactory->createProduct();
    myProduct->operation();
    delete myProduct;
    myProduct = NULL;
    delete myFactory;
    myFactory = NULL;
}

注意:在上述两个实现中,为简单起见,并没有定义构造函数和虚构函数。其中,基类的析构函数应为虚函数,这样才能保证,delete操作能够调用合适的析构函数。

逆向实战:如何绕过iTunes 12.6.5.3的反调试机制(附X64dbg插件配置) 本文深入剖析了iTunes 12.6.5.3的反调试机制与登录协议。通过X64dbg动态调试与IDA静态分析,详细演示了如何绕过其反调试检测,并定位到核心的登录协议加密函数,揭示了其请求签名(X-Apple-ActionSignature)的生成逻辑与依赖关系,为客户端安全研究与协议分析提供了实战思路。 阅读详情

相关推荐

SAP-MM-采购申请字段解析

采购申请抬头以及行项目字段解析

yanzibing99的博客 7306

Java 设计模式——单例模式

本文介绍了单例模式的相关知识。

代码星辰的博客 6073

【Office激活】学校正版Office已激活成功仍弹出激活窗口

学校正版Office激活问题:已激活成功仍弹出激活窗口

ESCM_的博客 1万+

MVC设计模式---数据库单例设计 实现用户的登录、注册

【Qt学习】MVC设计 完成数据库单例 登录 & 注册 功能实现

m0_56051805的博客 1858

Openwifi 开源项目解读(一)

Openwifi wifi 80211 无线网卡 基带 FPGA linux 驱动 开源

2万+

《通信工程施工与管理》

制作馈线接头必须使用专用的工具,专用工具包括:馈线切割刀、馈线安全刀、小金属丝毛刷、固定尺寸或大号活动扳手、小号扁锉刀、细齿小手锯、接头扩孔器、3M防水胶或防水接头盒;如图所示,详情如表所示。

2302_78710464的博客 1653

登录设计模式(工厂模式+模版方法模式+策略模式)

用户登录抽象类 定义login的模版方法(定义基本登录骨架) 1.抽象出check方法 2.userNotExistsHandler方法让子类来实现 子类:(2个登录类型,手机号验证码登录,账号密码登录)如下代码并实现了spring的监听器接口 容器在启动的时候会从容器中获取定义的用户权限处理的,并更具类型存到map登录类型存到map中。serivce层登录的实现。

superhaox的博客 735

Python3 ACM模式输入输出全攻略:从牛客网到华为机试的实战技巧

本文详细解析了Python3在ACM模式下的输入输出处理技巧,针对牛客网、华为机试等在线评测系统。文章从input()函数本质出发,总结了六种高频输入模式的处理模板,并提供了链表、二叉树等数据结构的I/O实战方案,最后给出性能优化与常见避坑指南,帮助开发者高效应对算法笔试。

zero1的博客 998

工厂模式和单例模式的实现

python中的工厂模式和单例模式的例子

freeline的博客 1027

Rocky Linux 9 远程桌面配置全攻略:从零搭建XRDP服务(含防火墙设置)

本文提供了在Rocky Linux 9上从零开始配置XRDP远程桌面服务的完整指南。详细介绍了系统准备、XRDP服务安装、防火墙与SELinux安全设置、多用户性能优化以及多平台客户端连接实测。重点解决了使用Windows远程桌面协议(RDP)连接Rocky Linux时常见的配置难点与安全问题,帮助用户获得稳定高效的图形化远程访问体验。

vodka的博客 649

腾讯开源CubeSandbox:为Agent打造可随时丢弃的安全沙箱环境

在人工智能与自动化技术快速发展的今天,智能体(Agent)在执行复杂任务时往往需要独立、完整的计算环境,但环境失控带来的安全风险一直是落地瓶颈。为解决这一痛点,可丢弃式沙箱技术应运而生。它通过轻量虚拟化原理实现环境秒级重建,并严格隔离宿主资源,即使Agent执行了恶意或误操作,也不会波及其他系统。这种技术价值在于平衡了灵活性与安全性,使开发者敢于赋予Agent更多自主操作权限。目前,这类技术已广泛应用于AI编程、自动化测试、数字员工、恶意代码分析等真实场景,成为Agent可靠运行的基石。腾讯开源的CubeS

weixin_42539414的博客 256

【设计模式学习】单例模式和工厂模式

设计模式是在软件设计中反复出现的问题和解决方案的经验总结。它是对软件设计中常见问题的通用解决方案,可以帮助设计人员更高效地解决问题,并提高软件设计的质量和可维护性。设计模式提供了一种在特定情况下的解决方案,它们可以被反复使用,并且是经过验证的最佳实践。设计模式可以帮助开发人员更好地理解软件设计中的问题,并为他们提供一种标准的方法来解决这些问题。通俗易懂的一点来说:就是提高你的下限。

xiaoxie8023的博客 3001

麦克风声源定位原理_声源定位—如何定位到噪声根源?

前言TPA(传递路径分析)专题系列已经开篇。其遵循方法论:源(Source)——路径(Path)——响应(Receiver)有人说TPA好,它可以识别出路径处甚至源的载荷特征,可以量化各个路径的贡献量。有人说声源定位好,不管东西南北中,“源”自其中。但是,声源定位识别出来色彩丰富的一个结果,这结果被您拿来应付工作了,还是真正帮您解决了问题?声源定位定位到了噪声的根源了么?对于一些声源现,...

weixin_39943678的博客 3973

java设计模式之单例模式和简单工厂模式

深度探讨java设计模式一、单例模式二、简单工厂模式 一、单例模式 1、单例类只能有一个实例。 2、单例类必须自己创建自己的唯一实例。 3、单例类必须给所有其他对象提供这一实例。 代码: // An highlighted block /** * 第一种:单例模式 */ public class demo01 { private static demo01 d = null; ...

weixin_39398544的博客 492

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

设计模式:单例模式和工厂模式

单例模式与工厂模式的基本原理和实现,以及单例模式结合工厂模式的基本应用。

Sinder小德的博客 6786

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Java设计模式-单例模式和工厂模式的思路解析

Java设计模式-单例模式和工厂模式

weixin_52937170的博客 1632

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

设计模式之简单工厂和单例模式

近段时间发现自己越来越懒了,老师早就讲过的东西,一直没有总结!百度了一下,给的答案是设计模式总共23种。简单工厂属于其中一种,而单例模式并不是其中一种。今天总结下使用这两种模式写的项目。 设计模式:设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,...

132

Java设计模式之单例模式和工厂模式

Java设计模式之单例模式和工厂模式 设计模式是程序员们在开发中总结的编码套路 单例模式 一个类只能创建出一个实例对象 饿汉式 思路:直接将唯一的实例对象创建出来 懒汉式 思路:只有在需要获取对象时,才会创建实例 懒汉式-进阶版 思路:在懒汉式的基础上,利用同步代码块+二次校验尽可能提高线程效率 工厂模式 对象的创建和销毁全部交由工厂完成,也是底层技术,通常用于底层框架 ​

weixin_57415255的博客 486

Java最常见设计模式:单例模式、工厂模式和代理模式

一、设计模式的分类 总体来说23种设计模式分为三大类: 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 我们主要来了解一下: 单例模式(Singleton) 简单的工厂模式(Factory) 代理模式(Proxy) 1. 单例模式

huangdong50的博客 3433

设计模式之单例模式和工厂模式(代码+举例)

面试常问的2种设计模式,单例模式的两种实现 饿汉式 懒汉式等

Panci_的博客 1759

python中的设计模式_工厂模式和单例模式

工厂模式 设计模式是面向对象语言特有的内容,是我们在面临某一类问题时候固定的做法,设计模式有很多种,比较流行的是:GOF(GoupOfFour)23种设计模式。 工厂模式实现了创建者和调用者的分离,使用专门的工厂类将选择实现类、创建对象进行统一的管理和控制。 #测试工厂模式 class CarFactory: def create_car(self,brand): if brand =="奔驰": return Benz() elif bra

每天都要进步的博客 452

php手写工厂和单例模式,详解PHP设计模式中工厂模式和单例模式

PHP设计模式之工厂模式与单例模式本文实例讲述了PHP设计模式之工厂模式与单例模式实现方法。分享给大家供大家参考,具体如下:设计模式简单说应对某类问题而设计的解决方式工厂模式:应对需求创建相应的对象class factory{function __construct($name){if(file_exists('./'.$name.'.class.php')){return new $name;}...

weixin_35509069的博客 229

php手写工厂和单例模式,PHP设计模式之工厂模式与单例模式

本文实例讲述了PHP设计模式之工厂模式与单例模式实现方法。分享给大家供大家参考,具体如下:设计模式简单说应对某类问题而设计的解决方式工厂模式:应对需求创建相应的对象class factory{function __construct($name){if(file_exists('./'.$name.'.class.php')){return new $name;}else{die('not exi...

weixin_42513944的博客 114

python常用设计模式,单例模式和工厂设计模式

python常用设计模式,单例和工厂设计模式Demo。

weixin_45568391的博客 523

php工厂模式和单例模式,php设计模式中工厂模式和单例模式的区别

//让该类在外界无法造对象//让外界可以造一个对象,做一个静态方法返回对象//在类里面通过让静态变量控制返回对象只能是一个。单例模式的要点有三个:一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。为什么要使用PHP单例模式1. php的应用主要在于数据库应用, 一个应用中会存在大量的数据库操作, 在使用面向对象的方式开发时, 如果使用单例模式, 则可以避免...

weixin_39646725的博客 252
上一篇: C++继承与组合的区别
下一篇: 字典树及其C++实现
蓬莱道人
博客等级 码龄11年 766粉丝 274原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值