常用设计模式在C++中的实现

设计模式是软件开发中解决常见问题的可重用解决方案。它们帮助开发者编写可维护、可扩展和高效的代码。本教程将介绍几种常用的设计模式,并通过C++代码示例展示它们的实现。

1. 单例模式 (Singleton Pattern)

1.1 理论解释

单例模式确保一个类只有一个实例,并提供一个全局访问点。这在需要全局唯一实例的场景中非常有用,例如日志记录器或配置管理器。

1.2 代码示例

#include <iostream>

class Singleton {
public:
    static Singleton& getInstance() {
        static Singleton instance;
        return instance;
    }

    void showMessage() {
        std::cout << "Hello from Singleton!" << std::endl;
    }

private:
    Singleton() {}  // 私有构造函数
    Singleton(const Singleton&) = delete;  // 禁用拷贝构造函数
    Singleton& operator=(const Singleton&) = delete;  // 禁用赋值运算符
};

int main() {
    Singleton& singleton = Singleton::getInstance();
    singleton.showMessage();
    return 0;
}

1.3 实践练习

修改单例类,使其能够记录创建实例的次数,并在每次调用showMessage时显示该次数。

2. 工厂模式 (Factory Pattern)

2.1 理论解释

工厂模式提供了一种创建对象的方式,而不需要指定具体的类。它通过定义一个接口来创建对象,让子类决定实例化哪个类。

2.2 代码示例

#include <iostream>
#include <string>

class Product {
public:
    virtual void use() = 0;
};

class ConcreteProductA : public Product {
public:
    void use() override {
        std::cout << "Using Product A" << std::endl;
    }
};

class ConcreteProductB : public Product {
public:
    void use() override {
        std::cout << "Using Product B" << std::endl;
    }
};

class Factory {
public:
    virtual Product* createProduct() = 0;
};

class ConcreteFactoryA : public Factory {
public:
    Product* createProduct() override {
        return new ConcreteProductA();
    }
};

class ConcreteFactoryB : public Factory {
public:
    Product* createProduct() override {
        return new ConcreteProductB();
    }
};

int main() {
    Factory* factoryA = new ConcreteFactoryA();
    Product* productA = factoryA->createProduct();
    productA->use();

    Factory* factoryB = new ConcreteFactoryB();
    Product* productB = factoryB->createProduct();
    productB->use();

    delete factoryA;
    delete factoryB;
    delete productA;
    delete productB;

    return 0;
}

2.3 实践练习

扩展工厂模式,添加一个新的产品类型ConcreteProductC,并创建相应的工厂类ConcreteFactoryC。

3. 观察者模式 (Observer Pattern)

3.1 理论解释

观察者模式定义了一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都会收到通知并自动更新。

3.2 代码示例

#include <iostream>
#include <vector>
#include <algorithm>

class Observer {
public:
    virtual void update(int value) = 0;
};

class Subject {
public:
    void attach(Observer* observer) {
        observers.push_back(observer);
    }

    void detach(Observer* observer) {
        observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
    }

    void notify(int value) {
        for (auto observer : observers) {
            observer->update(value);
        }
    }

private:
    std::vector<Observer*> observers;
};

class ConcreteObserver : public Observer {
public:
    ConcreteObserver(Subject& subject) : subject(subject) {
        subject.attach(this);
    }

    void update(int value) override {
        std::cout << "Observer received update: " << value << std::endl;
    }

private:
    Subject& subject;
};

int main() {
    Subject subject;
    ConcreteObserver observer1(subject);
    ConcreteObserver observer2(subject);

    subject.notify(10);

    return 0;
}

3.3 实践练习

修改观察者模式,使其能够处理多个不同的主题(Subject),并让观察者订阅不同的主题。

4. 策略模式 (Strategy Pattern)

4.1 理论解释

策略模式定义了一系列算法,并将每个算法封装起来,使它们可以互换。策略模式让算法独立于使用它的客户端而变化。

4.2 代码示例

#include <iostream>

class Strategy {
public:
    virtual void execute() = 0;
};

class ConcreteStrategyA : public Strategy {
public:
    void execute() override {
        std::cout << "Executing Strategy A" << std::endl;
    }
};

class ConcreteStrategyB : public Strategy {
public:
    void execute() override {
        std::cout << "Executing Strategy B" << std::endl;
    }
};

class Context {
public:
    Context(Strategy* strategy) : strategy(strategy) {}

    void setStrategy(Strategy* strategy) {
        this->strategy = strategy;
    }

    void executeStrategy() {
        strategy->execute();
    }

private:
    Strategy* strategy;
};

int main() {
    ConcreteStrategyA strategyA;
    ConcreteStrategyB strategyB;

    Context context(&strategyA);
    context.executeStrategy();

    context.setStrategy(&strategyB);
    context.executeStrategy();

    return 0;
}

4.3 实践练习

扩展策略模式,添加一个新的策略ConcreteStrategyC,并在Context类中添加一个方法,允许动态切换策略。

5. 适配器模式 (Adapter Pattern)

5.1 理论解释

适配器模式允许接口不兼容的类一起工作。它通过包装一个类的接口来适配另一个类的接口。

5.2 代码示例

#include <iostream>

class Target {
public:
    virtual void request() = 0;
};

class Adaptee {
public:
    void specificRequest() {
        std::cout << "Adaptee's specific request" << std::endl;
    }
};

class Adapter : public Target {
public:
    Adapter(Adaptee* adaptee) : adaptee(adaptee) {}

    void request() override {
        adaptee->specificRequest();
    }

private:
    Adaptee* adaptee;
};

int main() {
    Adaptee* adaptee = new Adaptee();
    Target* target = new Adapter(adaptee);
    target->request();

    delete adaptee;
    delete target;

    return 0;
}

5.3 实践练习

修改适配器模式,使其支持多个适配器,并在客户端代码中动态选择适配器。

6. 总结

本教程介绍了五种常用的设计模式:单例模式、工厂模式、观察者模式、策略模式和适配器模式。每种模式都有其特定的应用场景和实现方式。通过学习和实践这些设计模式,你将能够编写更加灵活、可维护和可扩展的C++代码。

7. 进一步学习

  • SOLID原则: 了解面向对象设计的五大原则,帮助你编写更好的代码。
  • 代码重构技巧: 学习如何在不改变外部行为的情况下改进代码结构。
  • 性能优化策略: 掌握优化C++代码性能的技巧。

通过不断实践和学习,你将能够熟练应用这些设计模式,并在实际项目中发挥它们的作用。