以下是 C++ 中一些常用的设计模式:
一、创建型设计模式
-
单例模式(Singleton Pattern)
-
目的:
- 确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。
-
实现方式:
- 通常将类的构造函数设为私有,防止外部直接创建实例。然后提供一个静态方法来获取该类的唯一实例。例如:
-
class Singleton { private: static Singleton* instance; Singleton() {} public: static Singleton* getInstance() { if (instance == nullptr) { instance = new Singleton(); } return instance; } }; Singleton* Singleton::instance = nullptr;
-
应用场景:
- 数据库连接池,在整个应用程序中只需要一个数据库连接池实例来管理数据库连接。
- 日志记录器,只需要一个实例来记录整个系统的日志信息。
-
工厂模式(Factory Pattern)
-
目的:
- 提供一种创建对象的方式,将对象的创建和使用分离。
-
实现方式:
- 定义一个工厂类,其中包含创建对象的方法。例如,创建一个形状工厂:
class Shape { public: virtual void draw() = 0; }; class Circle : public Shape { public: void draw() override { std::cout << "绘制圆形" << std::endl; } }; class Rectangle : public Shape { public: void draw() override { std::cout << "绘制矩形" << std::endl; } }; class ShapeFactory { public: static Shape* createShape(const std::string& type) { if (type == "circle") { return new Circle(); } else if (type == "rectangle") { return new Rectangle(); } return nullptr; } };
-
应用场景:
- 在游戏开发中,创建不同类型的游戏角色或游戏道具。
- 在图形绘制软件中,创建不同类型的图形对象。
-
二、结构型设计模式
-
代理模式(Proxy Pattern)
-
目的:
- 为其他对象提供一种代理以控制对这个对象的访问。
-
实现方式:
- 定义一个代理类,代理类和被代理类实现相同的接口。例如,创建一个图像代理
class Image { public: virtual void display() = 0; }; class RealImage : public Image { private: std::string fileName; public: RealImage(const std::string& fileName) : fileName(fileName) {} void display() override { std::cout << "显示图像: " << fileName << std::endl; } }; class ProxyImage : public Image { private: RealImage* realImage; std::string fileName; public: ProxyImage(const std::string& fileName) : fileName(fileName), realImage(nullptr) {} void display() override { if (realImage == nullptr) { realImage = new RealImage(fileName); } realImage->display(); } };
-
应用场景:
- 在网络访问中,代理服务器可以代理用户对某些网站的访问,进行访问控制、缓存等操作。
- 在加载大型图像或资源时,先使用代理显示占位符,当真正需要显示时再加载真实资源。
-
装饰器模式(Decorator Pattern)
-
目的:
- 动态地给一个对象添加一些额外的职责,就增加功能来说,装饰器模式相比继承更为灵活。
-
实现方式:
- 定义一个抽象装饰器类,它和被装饰类实现相同的接口,装饰器类内部包含一个指向被装饰类的指针。例如,给饮料添加配料:
class Beverage { public: virtual double cost() = 0; }; class Coffee : public Beverage { public: double cost() override { return 1.0; } }; class CondimentDecorator : public Beverage { protected: Beverage* beverage; public: CondimentDecorator(Beverage* beverage) : beverage(beverage) {} }; class Milk : public CondimentDecorator { public: Milk(Beverage* beverage) : CondimentDecorator(beverage) {} double cost() override { return beverage->cost() + 0.5; } }; class Sugar : public CondimentDecorator { public: Sugar(Beverage* beverage) : CondimentDecorator(beverage) {} double cost() override { return beverage->cost() + 0.2; } };
-
应用场景:
- 在图形用户界面(GUI)开发中,可以动态地给组件添加边框、滚动条等功能。
- 在电商系统中,可以给商品动态添加促销标签、折扣等功能。
- 定义一个抽象装饰器类,它和被装饰类实现相同的接口,装饰器类内部包含一个指向被装饰类的指针。例如,给饮料添加配料:
-
- 定义一个代理类,代理类和被代理类实现相同的接口。例如,创建一个图像代理
-
- 定义一个工厂类,其中包含创建对象的方法。例如,创建一个形状工厂:
-
三、行为型设计模式
-
观察者模式(Observer Pattern)
-
目的:
- 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
-
实现方式:
- 定义一个抽象的观察者接口和一个抽象的被观察对象接口。被观察对象维护一个观察者列表,当自身状态改变时,通知列表中的观察者。例如:
class Observer { public: virtual void update() = 0; }; class Subject { private: std::vector<Observer*> observers; public: void attach(Observer* observer) { observers.push_back(observer); } void detach(Observer* observer) { for (auto it = observers.begin(); it!= observers.end(); ++it) { if (*it == observer) { observers.erase(it); break; } } } void notify() { for (auto observer : observers) { observer->update(); } } };
-
应用场景:
- 在股票市场系统中,当股票价格发生变化时,通知所有关注该股票的投资者。
- 在社交媒体平台上,当用户发布新内容时,通知其所有的关注者。
-
策略模式(Strategy Pattern)
-
目的:
- 定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
-
实现方式:
- 定义一个抽象策略类,包含算法的接口,然后定义具体的策略类实现这些接口。例如,在一个电商系统中计算折扣:
-
- 定义一个抽象的观察者接口和一个抽象的被观察对象接口。被观察对象维护一个观察者列表,当自身状态改变时,通知列表中的观察者。例如:
-
class DiscountStrategy { public: virtual double calculateDiscount(double price) = 0; }; class NoDiscount : public DiscountStrategy { public: double calculateDiscount(double price) override { return 0.0; } }; class TenPercentDiscount : public DiscountStrategy { public: double calculateDiscount(double price) override { return price * 0.1; } }; class ShoppingCart { private: DiscountStrategy* discountStrategy; public: ShoppingCart(DiscountStrategy* discountStrategy) : discountStrategy(discountStrategy) {} double calculateTotal(double price) { return price - discountStrategy->calculateDiscount(price); } };
-
应用场景:
- 在导航软件中,根据用户选择的交通方式(如驾车、步行、公交)采用不同的路线规划策略。
- 在游戏中,根据不同的游戏模式(如单人模式、多人合作模式、多人对战模式)采用不同的游戏规则策略。
喜欢的同学可以点点关注!咱们下期再见!