设计模式 #
零、反射 #
含义 #
在程序运行时,动态获取对象信息以及调用对象方法的能力。
要解决的问题 #
在程序运行时,通过类的名称字符串来生成类的对象。
一、简单工厂模式 #
含义 #
把实例化的操作单独放到一个类中,即:工厂负责生产对象。
要解决的问题 #
让使用者不需要知道内部细节,就能创建对象,实现解耦。
组成 #
- 抽象的Product,描述接口。
- 具体Product, 创建的目标类。
- 工厂类,被外界调用,根据传入不同参数从而创建不同类的实例。
实际代码 #
工厂类有个静态方法,可以用switch case控制返回哪个类的实例。外界只要调用并传入参数即可。
改进:通过反射机制,去掉switch case,添加新Product不用修改。
应用场景 #
- 当外界/客户端只关心传入参数,不关心内部逻辑时,解耦
缺点 #
- 处于中心位置,需要知道所有创建细节,职责过于繁重;
- 要加新的产品时,要修改工厂类。
二、工厂方法模式 #
含义 #
定义一个用于创建对象的接口,由子类决定要实例化哪个类。工厂方法把实例化操作推迟到子类。
要解决的问题 #
- 让使用者不需要知道内部细节,就能创建对象,实现解耦。
- 新加产品时,只要添加具体产品和具体工厂就可以。
组成 #
- 抽象的Product:描述接口。
- 具体Product:具体产品。
- 抽象工厂类
- 具体工厂类
实际代码 #
客户端怎么调用?
- new 具体工厂,得到具体工厂实例;
- 用具体工厂,得到具体Product类。
应用场景 #
- 写日志到文件/数据库
三、抽象工厂 #
含义 #
创建的是对象家族,也就是很多对象而不是一个对象,并且这些对象是相关的,也就是说必须一起创建出来。而工厂方法模式只是用于创建一个对象,这和抽象工厂模式有很大不同。
要解决的问题 #
- 让使用者不需要知道内部细节,就能创建对象,实现解耦。
- 新加产品时,只要添加具体产品和具体工厂就可以。
组成 #
- 抽象的Product:描述接口。
- 具体Product:具体产品。
- 抽象工厂类
- 具体工厂类
实际代码 #
Client 通过 AbstractFactory 同时调用两个方法来创建出两个对象
客户端怎么调用?
- new 具体工厂,得到具体工厂实例;
- 用具体工厂,得到具体Product类。
应用场景 #
四、策略模式 #
- 目的:如果对象的某个行为,在不同的场景中有不同的实现方式,即有多种策略或算法,不要用很多个的if-else去做判断和选择,而是封装每个策略,并使它们可以切换,从而达到解耦的效果,满足开闭原则。
- 具体:三种角色
- 策略接口:负责定义接口
- 具体的策略:负责实现
- Context上下文:保存具体策略的实例。可以动态地改变具体的策略。
- 实例:多种支付方法(支付宝、微信支付)、多种分享方法(微信、QQ)。
五、单例模式 #
含义 #
确保一个类只有一个实例,并提供该实例的全局访问点。
实现方式 #
- 单例类:
- 构造函数私有化
- 有个私有的静态指针变量
- 有个共有的静态方法获取实例
- 饿汉式:还没被用到,就先初始化
- 懒汉式
class Singleton {
private:
Singleton() {};
~Singleton() {};
Singleton(const Singleton&) {}; // 拷贝构造函数
Singleton& operator=(const Singleton&); // 赋值构造函数
public:
static Singleton& getInstance() {
static Singleton instance; // 保证内部静态变量的线程安全性
return instance;
}
}