设计模式/

设计模式帮助开发者用更优雅、可复用的方式解决常见问题,提高代码的可读性、可维护性和可扩展性。熟练掌握这些模式,是面向对象设计进阶的重要一步。

设计模式分类

创建型、结构性、行为型

创建型:单例、工厂方法、抽象工厂、建造者...

结构性:适配器、桥接、组合、装饰、外观...

行为型:模板方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式

单例设计模式

一个类,全局永远只有一个实例,并且提供一个全局访问点。

使用场景

配置类、日志工具类、数据库连接、线程池、缓存对象

核心特点

构造方法私有(禁止外部 new)

提供静态方法获取唯一实例

全局唯一,不重复创建

设计过程

1.私有化构造函数

2.删除拷贝构造与赋值重载

3.公开静态成员函数

4.当前类对象 定义在私有或者 静态成员函数内定义静态的类对象

饿汉式

程序启动就创建好实例,天生线程安全。

优点:线程安全、简单

缺点:不用也会创建,浪费一点资源

懒汉式

最经典,但线程不安全。第一次使用才创建。

多线程下会创建多个实例,不安全

双重检查锁(DCL)线程安全

线程安全 + 懒加载。

优点:线程安全、懒加载、性能高

为什么要两次检查

  1. 第一次检查(不加锁)

    • 实例已经创建 → 直接返回,不用加锁,速度极快
    • 实例未创建 → 才进入加锁逻辑
  2. 加锁

    • 保证同一时间只有一个线程能创建实例
  3. 第二次检查(加锁后)

    • 防止多个线程同时卡在第一次检查
    • 确保只创建一次实例

面试题

为什么单例要私有构造?

防止外部 new 破坏单例。

饿汉式 vs 懒汉式区别?

饿汉:类加载就创建,线程安全;

懒汉:用到才创建,节省资源。

双重检查为什么要加 volatile?

防止 new Singleton() 指令重排,导致空指针。

如何防止反射破坏单例?

用枚举单例最安全。

工厂模式

简单工厂、工厂方法、抽象工厂

简单工厂模式(Simple Factory Pattern)是一种创建型设计模式,它通过一个工厂类来负责创建所有产品对象,客户端只需要告:诉工厂需要什么产品,工厂就会返回相应的产品实例。

简单工厂

依据用户需求,创建特定的产品

创建过程

1.设计产品的基类

2.设计具体的产品

3.设计简单工厂类

4.根据需求创建产品

核心特点

1.只有一个工厂类

2.根据传入的参数决定创建哪种产品

3.将对象的创建和使用分离

cpp 复制代码
#include <memory>
class Phone {//接口类
public:
	virtual void tell(string phone) = 0;
};

class MiPhone :public Phone {
public:
	void tell(string phone)override {
		cout << "MiPhone tell:" << phone << endl;
	}
};

class HuaWeiPhone :public Phone {
public:
	void tell(string phone)override {
		cout << "HuaWeiPlone tell:" << phone << endl;
	}
};

class VivoPhone :public Phone {
public:
	void tell(string phone)override {
		cout << "VivoPlone tell:" << phone << endl;
	}
};

class PhoneFactory {
public:
	enum Type{Mi,HuaWei,Vivo};
	static unique_ptr<Phone> create(Type type) {
		switch (type) {
		case Mi:return unique_ptr<Phone>(new MiPhone());
		case HuaWei:return unique_ptr<Phone>(new HuaWeiPhone());
		case Vivo:return unique_ptr<Phone>(new VivoPhone());
		}
		return nullptr;
	}
};

int main() {
	unique_ptr<Phone>phone = PhoneFactory::create(PhoneFactory::Vivo);
	phone->tell("110");

	unique_ptr<Phone>phone2 = PhoneFactory::create(PhoneFactory::HuaWei);
	phone->tell("120");

	return 0;
}

工厂方法

工厂方法模式 (Factory Method Pattern)是一种创建型设计模式,它定义了用于创建对象的接口,但让子类决定实例化哪一个类。工厂方法将对象的实例化延迟到子类中完成。

解决简单工厂创建产品的局限性

设计核心思想

将工厂创建产品抽象为一个接口,具体创建某一种产品由工厂的派生类来完成。

创建过程

1.定义工厂的接口类

2.定义生产具体产品的工厂派生类

cpp 复制代码
//工厂方法
class PhoneFactory {
public:
	//工厂的创建产品的函数(方法)
	virtual shared_ptr<Phone>create() = 0;
};

class HuaWeiFactory :public PhoneFactory {
public:
	shared_ptr<Phone>create()override {
		return shared_ptr<Phone>(new HuaWeiPhone());
	}
};

class MiFactory :public PhoneFactory {
public:
	shared_ptr<Phone>create()override {
		return shared_ptr<Phone>(new MiPhone());
	}
};

class VivoFactory :public PhoneFactory {
public:
	shared_ptr<Phone>create()override {
		return shared_ptr<Phone>(new VivoPhone());
	}
};

int main() {
	shared_ptr<Phone>hwPhone = HuaWeiFactory().create();
	hwPhone->tell("119");

	return 0;
}

核心特点

1.每个具体的产品对应一个具体的工厂

2.解决了简单工厂违反开闭原则的问题

3.符合"单一职责"和"开闭原则"

开闭原则:添加新产品只需添加新工厂类,无需修改现有代码。

单一职责:每个工厂只负责创建一种产品

抽象工厂

抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

基于工厂方法设计的,在工厂基类中,提供对产品的一些操作。

简单理解:抽象工厂将创建和使用组合到一起。

核心特点

1.创建产品族

2.一个工厂可以创建多种产品

3.强调产品之间的约束和关系

观察者模式

观察者模式是一种行为型设计模式,用于定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都会自动收到通知并更新。

一个主题(subject)被多个观察者(observer)监听(依赖),当主题的数据(成员变量)发生变量时,通知所有的观察者。

核心角色

Subject(被观察者/主题):管理观察者列表,状态变了通知所有人

Observer(观察者):有一个更新接口,被主题调用

ConcreteSubject:具体主题,存状态,状态变了触发通知

ConcreteObserver:具体观察者,收到通知做自己的事

Subject

维护观察者列表,提供 attach / detach / notify

Observer

定义 update 接口

ConcreteSubject

就是 Subject 结构体 + state + set_state

ConcreteObserver

就是 ConcreteObserver + 自己的 update 实现

相关推荐
一木 之林6 小时前
第 8 节 C++ 设计模式在 AI 推理 SDK 和 Agent 工具运行时中如何落地
c++·人工智能·设计模式
Zane199410 小时前
MVC 三层架构被打上反模式标签?一次账户扣款需求,讲清楚贫血模型和充血模型该怎么选
设计模式
geovindu1 天前
rust:Builder Pattern
开发语言·设计模式·rust·建造者模式
小王师傅661 天前
【设计模式】装饰模式(三):从装饰模式看 Java 与面向对象设计(原理篇)
设计模式
Zane19941 天前
从一次支付渠道扩展需求,看懂"多用组合少用继承"到底在说什么
设计模式
geovindu1 天前
CSharp:Condition Variable Pattern
后端·设计模式·c#·.net·.netcore·条件变量模式·同步型模式
geovindu1 天前
sql: Data Modeling Patterns using mysql
sql·mysql·设计模式·数据库开发
sarasuki2 天前
失败重试:Agent 中指数退避的正确姿势
人工智能·设计模式·agent
Zane19942 天前
为什么你写的 Java 代码"看着面向对象、实际是面向过程"?
设计模式
geovindu2 天前
sql: Data Modeling Patterns
数据库·sql·设计模式·sqlserver