单例模式和工厂模式

本文介绍了单例模式和工厂模式的基本概念、实现方法及其优缺点,并通过具体示例展示了这两种设计模式的应用。

1.单例模式

单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。

方法一:

public class Singleton{
    public static Singleton instance == null;
    private singleton() { } 
    public static Singleton getSingleton(){
        if(null == instance){
            instance = new Singleton();
        } 
        return instance;
    }
}



   方法二:

  1. public class Singleton2 {  
    	private static Singleton2 instance2 = null;  
    	public static synchronized Singleton2 getInstance() {  
     	if (instance2 == null)  
        		instance2 = new Singleton2();  
       		return instance2;  
    	}  
    } 
    



    优点

    一、实例控制
    单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。
    二、灵活性
    因为类控制了实例化过程,所以类可以灵活更改实例化过程。


  2. 2.工厂模式

  3. 工厂模式就是专门负责将大量有共同接口(或者共同抽象父类)的类实例化,而且不必事先知道每次是要实例化哪一个类的模式。它定义一个用于创建对象的接口,由子类决定实例化哪一个类。

  4. 优点
    工厂类是整个模式的关键.包含了必要的逻辑判断,根据外界给定的信息,决定究竟应该创建哪个具体类的对象.通过使用工厂类,外界可以从直接创建具体产品对象的尴尬局面摆脱出来,仅仅需要负责“消费”对象就可以了。而不必管这些对象究竟如何创建及如何组织的.明确了各自的职责和权利,有利于整个软件体系结构的优化。
    缺点
    由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中;它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了。
    当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求.这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模块功能的蔓延,对系统的维护和扩展非常不利;
    这些缺点在工厂方法模式中得到了一定的克服。
    使用场景
    工厂类负责创建的对象比较少;
    客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;
    由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。

具体例子:
一个Animal的抽象类
package com.bean;


public class Cat extends Animal{
@Override
	public void eat() {
		System.out.println("I am a Cat,I like eat fish!!");
	}
}

三个具体的动物类
package com.bean;


public class Cat extends Animal{
@Override
	public void eat() {
		System.out.println("I am a Cat,I like eat fish!!");
	}
}

package com.bean;


public class Dog extends Animal{

	@Override
	public void eat() {
		System.out.println("I am a dog,I like eat feat!!!!!");
		
	}
	
}

package com.bean;

public class Sheep extends Animal{
private String name;

public String getName() {
	return name;
}

public void setName(String name) {
	this.name = name;
}

@Override
public void eat() {
	// TODO Auto-generated method stub
	
}
}

工厂类

package com.factory;

import com.bean.Animal;

import com.bean.Cat;
import com.bean.Dog;
import com.bean.Sheep;


public class Animal_Factory {
	
	private static Animal animal = null;
		public static Animal getAnimal(String animal_name){
			if(animal_name.equals("Dog")){
				animal = new Dog();
			}
			
			if(animal_name.equals("Cat")){
				animal = new Cat();
			}
			
			if(animal_name.equals("Sheep")){
				animal = new Sheep();
			}
			return animal;
			
		}
	
	
	
}






测试类:
package com.factory.test;

import com.bean.Animal;
import com.factory.Animal_Factory;

public class Factory_Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Animal animal_a = Animal_Factory.getAnimal("Dog");
		animal_a.eat();
		Animal animal_b = Animal_Factory.getAnimal("Cat");
		animal_b.eat();

	}

}














<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++示说明。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值