C++ 中高级面试、工程实践高频考点,单例、工厂、观察者为核心,模板方法、策略、装饰器次之。掌握使用场景、UML 类图、代码实现,能应对场景设计题。
1. 单例模式(Singleton)
1.1 核心定义
确保一个类只有一个实例,并提供全局访问点。
1.2 适用场景
- 数据库连接池
- 日志管理器
- 配置管理中心
- 线程池
1.3 实现方式(必背)
饿汉式(静态成员)
cpp
class Singleton {
private:
static Singleton instance; // 静态成员在main前初始化
Singleton() {}
public:
static Singleton* getInstance() { return &instance; }
};
Singleton Singleton::instance; // 类外初始化
懒汉式(双检查锁)
cpp
class Singleton {
private:
static std::atomic<Singleton*> instance;
std::mutex mtx;
Singleton() {}
public:
static Singleton* getInstance() {
if (instance == nullptr) {
std::lock_guard<std::mutex> lock(mtx);
if (instance == nullptr) {
instance = new Singleton();
}
}
return instance.load();
}
};
1.4 注意事项
- 构造函数 private
- 拷贝构造、赋值运算符 delete
- 多线程安全(双检查锁)
- 饿汉 vs 懒汉:线程安全vs延迟加载
2. 工厂模式(Factory)
2.1 简单工厂
- 定义:一个工厂类,根据参数生产不同产品
- 优点:封装创建逻辑
- 缺点:违反开闭原则,新增产品需改工厂
模板:
cpp
class Product { public: virtual void use() = 0; };
class ProductA : public Product { public: void use() {} };
class ProductB : public Product { public: void use() {} };
class Factory {
public:
static Product* create(const string& type) {
if (type == "A") return new ProductA();
if (type == "B") return new ProductB();
return nullptr;
}
};
2.2 工厂方法
- 定义:抽象工厂 + 具体工厂,子类决定创建对象
- 优点:符合开闭原则
- 适用:产品系列稳定,产品种类扩展
2.3 抽象工厂
- 定义:一系列相关对象工厂接口
- 适用:产品族(一套产品一起用)
2.4 对比表
| 模式 | 优点 | 缺点 | 适用 |
|---|---|---|---|
| 简单工厂 | 简单 | 违反开闭 | 产品少 |
| 工厂方法 | 开闭 | 类多 | 产品扩展 |
| 抽象工厂 | 产品族 | 难扩展 | 产品族固定 |
3. 观察者模式(Observer)
3.1 核心定义
对象间一对多依赖,主题状态变化通知观察者。
3.2 适用场景
- 事件处理系统
- MVC 架构
- 消息推送
- 股票行情
3.3 实现模板
cpp
class Observer {
public:
virtual void update(int state) = 0;
};
class Subject {
private:
vector<Observer*> observers;
int state;
public:
void attach(Observer* o) { observers.push_back(o); }
void detach(Observer* o) { /* remove */ }
void notify() {
for (auto o : observers) o->update(state);
}
void setState(int s) { state = s; notify(); }
};
3.4 面试追问
- 观察者如何解耦? 完全不知道彼此存在
- 异步通知? 消息队列
- 缺点? 观察者太多性能差
4. 策略模式(Strategy)
4.1 核心定义
定义算法家族,相互替换,算法独立于客户。
4.2 适用场景
- 支付方式(微信/支付宝)
- 排序算法(快排/堆排)
- 压缩算法(Zip/RAR)
4.3 实现模板
cpp
class Strategy {
public:
virtual void algorithm() = 0;
};
class StrategyA : public Strategy {
public:
void algorithm() {}
};
class Context {
private:
Strategy* strategy;
public:
void setStrategy(Strategy* s) { strategy = s; }
void execute() { strategy->algorithm(); }
};
4.4 vs 简单工厂
- 简单工厂:对象由工厂创建
- 策略模式:对象由客户端选择算法
5. 装饰器模式(Decorator)
5.1 核心定义
动态附加职责,比继承更灵活。
5.2 适用场景
- IO 流包装(FileInputStream -> BufferedInputStream)
- 日志增强
- 权限增强
5.3 实现模板
cpp
class Component {
public:
virtual void operation() = 0;
};
class ConcreteComponent : public Component {
public:
void operation() {}
};
class Decorator : public Component {
protected:
Component* component;
public:
Decorator(Component* c) : component(c) {}
void operation() { component->operation(); }
};
class ConcreteDecorator : public Decorator {
public:
ConcreteDecorator(Component* c) : Decorator(c) {}
void operation() {
decoratorBefore();
component->operation();
decoratorAfter();
}
};
5.4 装饰器 vs 继承
- 装饰器:运行时动态添加
- 继承:编译期静态确定
6. 模板方法模式
6.1 核心定义
骨架 + 延迟实现,父类定义流程,子类实现细节。
6.2 适用场景
- 框架骨架
- 算法骨架
- 测试框架
6.3 实现模板
cpp
class AbstractClass {
public:
void templateMethod() {
step1();
step2();
step3();
}
virtual void step1() = 0;
virtual void step2() = 0;
virtual void step3() {} // 可选实现
};
class ConcreteClass : public AbstractClass {
public:
void step1() {}
void step2() {}
};
6.4 对比
- vs 策略:策略整个替换,模板方法部分替换
7. 适配器模式
7.1 核心定义
接口转换,兼容旧接口。
7.2 适用场景
- 旧系统集成
- 第三方库
- 亡羊补牢
7.3 分类
- 类适配器:多继承(Adapter 继承 Target + Adaptee)
- 对象适配器:组合(Adapter 持有 Adaptee 实例)
7.4 实现
cpp
class Target {
public:
virtual void request() = 0;
};
class Adaptee {
public:
void specificRequest() {}
};
class Adapter : public Target {
private:
Adaptee* adaptee;
public:
void request() { adaptee->specificRequest(); }
};
8. 代理模式
8.1 核心定义
控制访问,通过代理对象访问真实对象。
8.2 适用场景
- 远程代理(RMI)
- 虚代理(图片延迟加载)
- 保护代理(权限控制)
- 智能引用(自动释放)
8.3 分类
- 静态代理:编译时确定
- 动态代理:运行时反射(Java/C#)
8.4 实现
cpp
class Subject {
public:
virtual void request() = 0;
};
class RealSubject : public Subject {
public:
void request() {}
};
class Proxy : public Subject {
private:
RealSubject* realSubject;
public:
void request() {
// 前置处理
realSubject->request();
// 后置处理
}
};
9. 构建者模式(Builder)
9.1 核心定义
分步构建复杂对象,builder 负责各部分构建。
9.2 适用场景
- 复杂对象(StringBuilder)
- 多部件组合
- 产品类稳定,建造过程经常变化
9.3 实现
cpp
class Product {
private:
vector<string> parts;
public:
void addPart(string part) { parts.push_back(part); }
};
class Builder {
public:
virtual void buildPartA() = 0;
virtual void buildPartB() = 0;
virtual Product* getResult() = 0;
};
class ConcreteBuilder : public Builder {
private:
Product* product;
public:
ConcreteBuilder() { product = new Product(); }
void buildPartA() { product->addPart("A"); }
void buildPartB() { product->addPart("B"); }
Product* getResult() { return product; }
};
class Director {
public:
void construct(Builder* builder) {
builder->buildPartA();
builder->buildPartB();
}
};
10. 原型模式(Prototype)
10.1 核心定义
克隆对象,不通过 new 创建。
10.2 适用场景
- 对象创建成本大
- 相似对象
- 避免层次创建
10.3 实现
cpp
class Prototype {
public:
virtual Prototype* clone() = 0;
};
class ConcretePrototype : public Prototype {
private:
int value;
public:
ConcretePrototype(int v) : value(v) {}
Prototype* clone() {
return new ConcretePrototype(value);
}
};
10.4 深拷贝 vs 浅拷贝
- 浅拷贝:指针拷贝,析构两次
- 深拷贝:递归clone,资源独立
🔥 本章综合高频追问
-
问 :单例如何防反射?
答:在构造函数抛异常(无法完全防)
-
问 :工厂 vs 策略 区别?
答:工厂创建对象,策略替换算法
-
问 :装饰器 vs 继承 区别?
答:装饰器运行时,继承编译期
-
问 :代理 vs 装饰器 区别?
答:代理控制访问,装饰器增强功能
📝 模块总结
本模块覆盖设计模式核心 单例、工厂、观察者、策略、装饰器、代理,掌握 UML 类图、代码实现、适用场景,能应对 80% 场景设计题。工程中优先组合,警惕过度设计。
