【C++】面试:设计模式

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,资源独立

🔥 本章综合高频追问

  1. :单例如何防反射?

    :在构造函数抛异常(无法完全防)

  2. :工厂 vs 策略 区别?

    :工厂创建对象,策略替换算法

  3. :装饰器 vs 继承 区别?

    :装饰器运行时,继承编译期

  4. :代理 vs 装饰器 区别?

    :代理控制访问,装饰器增强功能


📝 模块总结

本模块覆盖设计模式核心 单例、工厂、观察者、策略、装饰器、代理,掌握 UML 类图、代码实现、适用场景,能应对 80% 场景设计题。工程中优先组合,警惕过度设计。