单例模式和工厂模式

博客主要介绍了设计模式中的单例模式和工厂模式。单例模式有饿汉式和懒汉式,前者多线程安全但可能浪费内存,后者不占内存但线程不安全。工厂模式核心工厂类将创建工作交子类,实现开闭原则和可扩展,适用于产品结构复杂场合。

设计模式

1.单例模式

定义:

单例模式要求某一类能够有返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名称)。

使用场景:

1.需要频繁的进行创建和销毁的对象;
2.创建对象时耗时过多或耗费资源过多,但又经常用到的对象;
3.工具类对象;
4.频繁访问数据库或文件的对象。

创建方式:

  // 饿汉式:
    public class Singleton{
    //创建私有构造方法
    	private Singleton(){};
    	//创建私有静态的成员变量并实例化
    	private final static Singleton instance = new Singleton();
    	//静态工厂实例
        public static Singleton getInstance(){
        	return instance;
        }
    }


   // 懒汉式:
    public class Singleton{
      //创建私有构造方法
    	private Singleton(){};
    	//创建私有静态的成员变量
    	private Singleton instance=null;
    	//静态工厂实例
        public static Singleton getInstance(){
        	if(instance == null){
        		instance = new Singleton;
        	}
        	return instance;
        }
    }

所谓“懒汉式”与“饿汉式”的区别,是在与建立单例对象的时间的不同。
饿汉式”是在不管你用的用不上,一开始就建立这个单例对象:比如:有个单例对象
“懒汉式”是在你真正用到的时候才去建这个单例对象:

但是他们都有各自的优缺点:
1.饿汉式:
饿汉式优点: 在多线程模式下是安全的
饿汉式缺点:提前创建好对象,如果在整个项目中没有使用,浪费内存资源。
2.懒汉式
懒汉式优点:只有调用方法才创建对象,不会占用内存
懒汉式缺点:线程不安全,在多线程下,一个线程进入了if (singleton == null)判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例。
在这里插入图片描述
推荐用法:

public class Singleton{
	private Singleton(){};
    private static class SingleInstance{
        private final static Singleton ins = new Singleton();
    }
    public static Singleton getInstance(){
        return SingleInstance.ins;
    }
}

2.工厂模式

定义:

工厂方法模式Factory Method,又称多态性工厂模式。在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做。该核心类成为一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。实现‘开-闭 原则’,实现了可扩展。其次更复杂的层次结构,可以应用于产品结果复杂的场合。

代码实现:

核心类(抽象工厂)
public interface IFactory{
	ICar createCar();
}
汽车类
public interface ICar{
	void run();
}
public class baomaCar implements ICar{
	void run(){...}
}
public class aodiCar implements ICar{
	void run(){...}
}
实现具体工厂
public class baomaFactory implements IFactory{
	Icar createCar(){ return new baomaCar() }
}
public class aodiFactory implements IFactory{
	Icar createCar(){ return new aodiCar() }
}
<think>嗯...用户这次想明确了解C++中单例模式工厂模式的区别及使用场景。从查询语气看应该是位有一定编程基础的开发者,可能在准备面试或架构设计时遇到了选择困难。注意到用户特意强调"不是真正需求"的引用资料里其实已经包含关键线索:的核心是控制实数量(全局唯一),工厂的核心是封装对象创建(解耦调用方与具体类)。不过用户上次的问题历史不可见,需要更聚焦于本次对比。工厂模式其实有三个细分类型(简/工厂方法/抽象工厂),但用户只提"工厂模式",根据引用[3]提到的"去静态属性""子类继承"等描述,判断用户主要指工厂方法模式。这点要在回答中说明以免混淆。用户用"请问"开头显得很礼貌,但"区别及使用场景"这个需求其实包含两个层面:技术实现差异哲学思想差异。需要分层解释:1)代码结构差异:有static实私有构造,工厂有产品继承体系2)设计目的差异:控资源,工厂促扩展3)典型场景对比:比如日志模块用(全局唯一),GUI控件库用工厂(多平台适配)特别注意C++特性:引用[2]展示的用delete禁用拷贝构造很关键,工厂模式在C++中往往需要配合虚基类使用。这点Java/C#开发者可能不敏感,但C++用户必须交代清楚内存管理影响。用户隐含需求可能是"何时选择哪种模式",所以区别要说透,但结尾要给出决策树式的场景建议。比如当遇到需要管理共享资源时选,需要支持未知子类扩展时选工厂。</think> 在C++中,单例模式工厂模式是两种截然不同的设计模式,核心目标实现方式均有本质差异,以下是二者的关键区别及典型使用场景: --- ### **一、核心区别** | **维度** | **单例模式 (Singleton)** | **工厂模式 (Factory)** | |------------------|------------------------------------------|------------------------------------------| | **核心目标** | 保证一个类**仅有一个实** | **封装对象创建过程**,解耦调用方与具体类 | | **实现关键** | 私有构造函数+静态实+全局访问点 | 抽象工厂/产品接口+具体工厂/产品实现类 | | **实数量控制** | 严格限制为1个 | 可创建任意数量的不同类实 | | **使用方式** | 通过静态方法获取唯一实 (`getInstance()`) | 通过工厂类创建新对象 (`createProduct()`) | --- ### **二、代码实现对比** #### **单例模式(懒汉式,线程不安全版)** ```cpp class Singleton { private: static Singleton* instance; Singleton() {} // 私有构造函数 public: Singleton(const Singleton&) = delete; // 禁用拷贝 Singleton& operator=(const Singleton&) = delete; // 禁用赋值 static Singleton* getInstance() { if (instance == nullptr) { instance = new Singleton(); } return instance; } }; Singleton* Singleton::instance = nullptr; // 静态成员初始化 ``` #### **工厂方法模式** ```cpp // 抽象产品 class Product { public: virtual void use() = 0; }; // 具体产品A class ConcreteProductA : public Product { public: void use() override { /* A的功能实现 */ } }; // 抽象工厂 class Factory { public: virtual Product* createProduct() = 0; }; // 具体工厂A class ConcreteFactoryA : public Factory { public: Product* createProduct() override { return new ConcreteProductA(); // 创建产品A } }; ``` --- ### **三、使用场景** | **模式** | **典型应用场景** | |----------------|--------------------------------------------------------------------------------| | **单例模式** | ✅ 全局配置类(如系统设置)<br/>✅ 日志管理器(所有模块共享同一日志器)<br/>✅ 线程池/连接池(避免资源冲突)<br/>✅ 缓存系统(统一数据存储) | | **工厂模式** | ✅ 需要支持多类对象创建(如不同数据库驱动)<br/>✅ 系统需独立于对象创建方式(如跨平台UI控件)<br/>✅ 扩展新产品时避免修改调用代码(开闭原则) | --- ### **四、本质差异总结** 1. **是"限制"**: - 通过技术手段强制限制实数量,聚焦**资源管控**。 - 如:数据库连接池必须全局唯一,避免资源浪费[^2]。 2. **工厂是"抽象"**: - 将对象创建逻辑抽象化,聚焦**扩展灵活性**。 - 如:支付系统中通过`PaymentFactory`创建`Alipay`/`WechatPay`实,新增支付方式无需修改业务逻辑[^3]。 > ⚠️ **注意**:二者可组合使用。如用单例模式管理全局唯一的工厂,再通过该工厂创建对象。 --- **相关问题** 1. 如何实现C++单例模式的线程安全版本? 2. 抽象工厂模式工厂方法模式有何区别? 3. 单例模式在哪些场景下可能成为设计缺陷? 4. 工厂模式如何遵循开闭原则?请用C++示说明。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值