C++ 程序设计:四大模式(工厂+装饰+策略+观察者)

这篇具有很好参考价值的文章主要介绍了C++ 程序设计:四大模式(工厂+装饰+策略+观察者)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.前言

"工厂+装饰+策略+观察者"是常见且常用的设计模式之一,但并不是指称"四大模式"的官方术语。

"四大模式"通常是指指令式面向对象编程中的四个基本概念:封装继承多态抽象。这四个概念是面向对象编程的基石。

2.工厂模式

工厂模式(例:工厂方法模式)中,通常存在一个抽象的工厂类和多个具体的工厂子类。每个工厂子类负责创建一种具体的对象,具体的创建逻辑在工厂子类中实现。客户端通过与工厂接口进行交互,并由工厂子类来创建所需的对象。

/* 将工厂也声明成一个基类 */             
class TaskBase
{
public:
    TaskBase();
    virtual ~CalculatorBase();
    virtual void exec(unsigned char *data) = 0; 
private:
    ...
};

class TaskA : public TaskBase
{
public:
    TaskA();
    ~TaskA();
    virtual void exec(unsigned char *data) override;
private:
    ...
};

class TaskB : public TaskBase
{
public:
    TaskA();
    ~TaskB();
    virtual void exec(unsigned char *data) override;
private:
    ...
};

int main() 
{
    TaskBase *task_1 = new TaskA();
    TaskBase *task_2 = new TaskB();
    TaskBase *current;
    
    int type = 1; // 进行工厂的选择
    
    if(type == 0)
        current = task_1;
    else
        current = task_2;

    current->exec();

    return 0;
}

这种模式特别适合task任务的选择 

3.装饰模式

装饰器模式是一种结构型设计模式,用于动态地给对象添加额外的行为,同时又不修改原始对象的结构。装饰器模式通过将对象包装在一个具有相同接口的装饰器类中,可以在运行时添加、修改或删除对象的功能。

装饰器模式的核心思想是使用继承和组合,通过创建具有相同接口的装饰器类来包装原始对象。装饰器类拥有与原始对象相同的接口,并持有一个指向原始对象的引用。装饰器类可以在执行原始对象的方法前后添加自定义的行为,以扩展原始对象的功能。

#include <iostream>
#include <string>

// 抽象订单接口
class Order 
{
public:
    virtual void process() = 0;
};

// 具体订单类
class SimpleOrder : public Order 
{
public:
    void process() override 
    {
        std::cout << "处理简单订单" << std::endl;
    }
};

// 抽象装饰器类
class OrderDecorator : public Order 
{
protected:
    Order* decoratedOrder;  // 持有一个指向原始订单的引用

public:
    OrderDecorator(Order* order) : decoratedOrder(order) {}

    void process() override 
    {
        decoratedOrder->process();
    }
};

// 具体装饰器类A
class UrgentOrderDecorator : public OrderDecorator 
{
public:
    UrgentOrderDecorator(Order* order) : OrderDecorator(order) {}

    void process() override 
    {
        OrderDecorator::process();
        std::cout << "添加急件处理" << std::endl;
    }
};

// 具体装饰器类B
class InternationalOrderDecorator : public OrderDecorator 
{
public:
    InternationalOrderDecorator(Order* order) : OrderDecorator(order) {}

    void process() override
    {
        OrderDecorator::process();
        std::cout << "添加国际订单处理" << std::endl;
    }
};

int main() 
{
    Order* order = new SimpleOrder();
    order->process();  // 处理简单订单

    Order* urgentOrder = new UrgentOrderDecorator(order);
    urgentOrder->process();  // 处理简单订单,并添加急件处理

    Order* internationalOrder = new InternationalOrderDecorator(order);
    internationalOrder->process();  // 处理简单订单,并添加国际订单处理

    Order* urgentInternationalOrder = new UrgentOrderDecorator(new InternationalOrderDecorator(order));
    urgentInternationalOrder->process();  // 处理简单订单,并同时添加国际订单和急件处理

    delete urgentInternationalOrder;
    delete internationalOrder;
    delete urgentOrder;
    delete order;

    return 0;
}

在这个例子中,抽象订单接口Order定义了订单的处理方法process()SimpleOrder是具体订单类,它实现了订单的处理逻辑。OrderDecorator是抽象装饰器类,它持有一个指向原始订单的引用,并在订单处理前后添加额外的功能。UrgentOrderDecoratorInternationalOrderDecorator是具体装饰器类,分别给订单添加了急件处理和国际订单处理。

客户端代码演示了不同的订单处理情况。通过创建不同的装饰器对象来包装原始订单对象,可以在处理订单时添加额外的功能。每个装饰器类都在执行原始订单的处理方法前后添加了自己特定的行为。

这个例子展示了装饰器模式的灵活性,可以在不修改订单类的情况下,动态地添加、修改或删除订单的功能。它允许通过装饰器组合来创建不同的订单处理方式。

处理简单订单

处理简单订单
添加急件处理

处理简单订单
添加国际订单处理

处理简单订单
添加国际订单处理
添加急件处理
处理简单订单
添加急件处理
添加国际订单处理

 4.策略模式

C++策略模式(Strategy Pattern)是一种行为设计模式,它允许在运行时动态地选择算法或行为。该模式将算法封装在独立的策略类中,使得它们可以相互替换,而不影响客户端代码。这种灵活性使得我们可以根据不同的情境选择不同的算法,提高代码的复用性和可维护性。 

#include <iostream>

// 定义抽象策略接口
class SendStrategy 
{
public:
    virtual void sendData(const std::string& data) const = 0;
};

// 定义具体策略类:UART发送
class UartStrategy : public SendStrategy 
{
public:
    void sendData(const std::string& data) const override 
    {
        std::cout << "UART发送数据:" << data << std::endl;
    }
};

// 定义具体策略类:TCP发送
class TcpStrategy : public SendStrategy 
{
public:
    void sendData(const std::string& data) const override 
    {
        std::cout << "TCP发送数据:" << data << std::endl;
    }
};

// 定义具体策略类:UDP发送
class UdpStrategy : public SendStrategy 
{
public:
    void sendData(const std::string& data) const override 
    {
        std::cout << "UDP发送数据:" << data << std::endl;
    }
};

// 定义环境类
class DataSender {
private:
    SendStrategy* strategy;

public:
    explicit DataSender(SendStrategy* strategy) : strategy(strategy) {}

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

    void sendData(const std::string& data) 
    {
        if (strategy) 
        {
            strategy->sendData(data);
        }
    }
};

int main() 
{
    // 创建具体策略对象
    SendStrategy* uart = new UartStrategy();
    SendStrategy* tcp = new TcpStrategy();
    SendStrategy* udp = new UdpStrategy();

    // 创建环境对象并设置初始策略
    DataSender sender(uart);

    // 发送数据
    sender.sendData("Hello, World!");

    // 切换为TCP发送
    sender.setStrategy(tcp);
    sender.sendData("Hello, TCP!");

    // 切换为UDP发送
    sender.setStrategy(udp);
    sender.sendData("Hello, UDP!");

    // 释放资源
    delete uart;
    delete tcp;
    delete udp;

    return 0;
}

我们首先定义了一个抽象策略接口SendStrategy,然后实现了三个具体的策略类UartStrategyTcpStrategyUdpStrategy,分别用于UART、TCP和UDP发送。

接着,我们定义了环境类DataSender,它维护了一个指向具体策略对象的引用,并提供了一个公共接口sendData()以供客户端代码调用。

在主函数中,我们创建了具体策略对象,并将初始策略设置为UART发送。然后,我们使用环境对象的sendData()方法来发送数据。

接着,我们切换策略为TCP发送和UDP发送,并分别调用环境对象的sendData()方法。

5.观察者模式

C++观察者模式(Observer Pattern)是一种行为设计模式,它使用一对多的依赖关系,当一个对象(主题)的状态发生变化时,自动通知并更新其他依赖于它的对象(观察者)。观察者模式提供了一种松耦合的方式,使得主题和观察者可以独立变化,而不需要相互了解具体的实现细节。

观察者模式的主要角色包括:

  1. Subject(主题):它通常是一个抽象类或接口,定义了增加、删除和通知观察者的方法。
  2. ConcreteSubject(具体主题):它是主题的具体实现,存储了具体观察者对象,并在状态发生变化时通知观察者。
  3. Observer(观察者):它定义了观察者接收通知并更新自己的方法。
  4. ConcreteObserver(具体观察者):它是观察者的具体实现,实现了接收通知和更新自身的方法。
#include <iostream>
#include <vector>

// 定义观察者接口
class Observer {
public:
    virtual void update(const std::string& news) = 0;
};

// 定义具体观察者类
class Subscriber : public Observer {
private:
    std::string name;

public:
    explicit Subscriber(const std::string& name) : name(name) {}

    void update(const std::string& news) override {
        std::cout << name << " 收到新闻:" << news << std::endl;
    }
};

// 定义主题类
class NewsChannel {
private:
    std::vector<Observer*> observers;
    std::string latestNews;

public:
    void addObserver(Observer* observer) {
        observers.push_back(observer);
    }

    void removeObserver(Observer* observer) {
        // 在实际应用中可能需要实现删除观察者的逻辑
    }

    void notifyObservers() {
        for (auto observer : observers) {
            observer->update(latestNews);
        }
    }

    void setNews(const std::string& news) {
        latestNews = news;
        notifyObservers();
    }
};

int main() {
    // 创建主题类(新闻频道)
    NewsChannel newsChannel;

    // 创建观察者类(订阅者)
    Observer* subscriber1 = new Subscriber("订阅者1");
    Observer* subscriber2 = new Subscriber("订阅者2");

    // 添加观察者到主题中
    newsChannel.addObserver(subscriber1);
    newsChannel.addObserver(subscriber2);

    // 发布新闻
    newsChannel.setNews("今天天气晴朗,适合出游!");

    // 释放资源
    delete subscriber1;
    delete subscriber2;

    return 0;
}

拓展:委托机制下的观察者模式文章来源地址https://www.toymoban.com/news/detail-584070.html

#include <iostream>
#include <vector>
#include <thread>
#include <mutex>

// 定义一个委托类
template<typename... Args>
class Delegate {
public:
    using FunctionPtr = std::function<void(Args...)>;

    void Add(FunctionPtr function) {
        std::lock_guard<std::mutex> lock(mutex);
        delegates.push_back(function);
    }

    void Remove(FunctionPtr function) {
        std::lock_guard<std::mutex> lock(mutex);
        delegates.erase(std::remove(delegates.begin(), delegates.end(), function), delegates.end());
    }

    void Invoke(Args... args) {
        std::lock_guard<std::mutex> lock(mutex);
        for (auto delegate : delegates) {
            delegate(args...);
        }
    }

private:
    std::vector<FunctionPtr> delegates;
    std::mutex mutex;
};

// 定义观察者基类
class Observer {
public:
    virtual void Notify() = 0;
};

// 定义具体观察者类
class ConcreteObserver : public Observer {
public:
    ConcreteObserver(Delegate<void>& delegate) : delegate(delegate) {}

    void Notify() override {
        // 当前线程接收到通知后的处理代码
        std::cout << "ConcreteObserver received notification in thread: " << std::this_thread::get_id() << std::endl;
    }

private:
    Delegate<void>& delegate;
};

// 定义主题类
class Subject {
public:
    void AddObserver(Observer* observer) {
        std::lock_guard<std::mutex> lock(mutex);
        observers.push_back(observer);
    }

    void RemoveObserver(Observer* observer) {
        std::lock_guard<std::mutex> lock(mutex);
        observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
    }

    void NotifyObservers() {
        std::lock_guard<std::mutex> lock(mutex);
        for (auto observer : observers) {
            observer->Notify();
        }
    }

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

// 工作线程函数
void WorkerThread(Subject& subject) {
    // 在工作线程中执行一些任务...
    // 完成后通知观察者
    std::this_thread::sleep_for(std::chrono::seconds(2)); // 模拟工作
    subject.NotifyObservers();
}

int main() {
    // 创建委托对象
    Delegate<void> delegate;

    // 创建观察者对象
    ConcreteObserver observer(delegate);

    // 创建主题对象
    Subject subject;

    // 将观察者注册到主题中
    subject.AddObserver(&observer);

    // 创建工作线程并传递主题对象
    std::thread workerThread(WorkerThread, std::ref(subject));

    // 主线程中执行其他任务
    std::cout << "Main thread doing some work..." << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(1));

    // 等待工作线程结束
    workerThread.join();

    return 0;
}

到了这里,关于C++ 程序设计:四大模式(工厂+装饰+策略+观察者)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python---闭包,装饰器,设计模式之工厂模式

    1.  闭包定义 定义双层嵌套函数, 内层函数可以访问外层函数的变量 将内存函数作为外层函数的返回,此内层函数就是闭包函数 2. 闭包的好处和缺点 优点:不定义全局变量,也可以让函数持续访问和修改一个外部变量 优点:闭包函数引用的外部变量,是外层函数的内部变

    2024年02月02日
    浏览(36)
  • 【设计模式与范式:行为型】61 | 策略模式(下):如何实现一个支持给不同大小文件排序的小程序?

    上一节课,我们主要介绍了策略模式的原理和实现,以及如何利用策略模式来移除 if-else 或者 switch-case 分支判断逻辑。今天,我们结合“给文件排序”这样一个具体的例子,来详细讲一讲策略模式的设计意图和应用场景。 除此之外,在今天的讲解中,我还会通过一步一步地

    2024年02月10日
    浏览(42)
  • 设计模式(单例模式、工厂模式及适配器模式、装饰器模式)

    目录 0 、设计模式简介 一、单例模式 二、工厂模式 三、适配器模式 四、装饰器模式  设计模式可以分为以下三种:  创建型模式: 用来描述 “如何创建对象” ,它的主要特点是 “将对象的创建和使用分离”。包括 单例 、原型、 工厂方法 、 抽象工厂 和建造者 5 种模式。

    2024年02月06日
    浏览(40)
  • 软件设计模式(二):工厂、门面、调停者和装饰器模式

            在这篇文章中,荔枝将会梳理软件设计模式中的四种:工厂模式、Facade模式、Mediator模式和装饰器Decorator模式。其中比较重要的就是工厂模式和装饰器模式,工厂模式在开发中使用的频数比较高。希望荔枝的这篇文章能讲清楚哈哈哈哈,希望能帮助到有需要的小伙

    2024年02月09日
    浏览(43)
  • 设计模式-策略工厂

    在介绍策略工厂的实现前,我们要先了解spring中beanFactory: BeanFactory 作为IOC服务的提供者,通过XmlBeanFactory来得到实例 生产Bean的工厂,采用延迟初始化策略(只有在需要某个对象时,才进行初始化和依赖注入); 通常会用xml文件来注册并管理各个业务对象之间的依赖关系

    2024年02月11日
    浏览(37)
  • 设计模式:策略模式和工厂模式混合使用

    有时单个设计模式并不能满足我们的业务需求,这个时候就要根据具体的业务来混合使用设计模式,其中策略模式和工厂模式是比较常用的一个组合。工厂模式可以管理具体策略的生命周期,策略模式可以丰满具体细节的逻辑。 在这个示例中,我们定义了一个策略接口和两个

    2024年02月07日
    浏览(35)
  • Java 大厂八股文面试专题-设计模式 工厂方法模式、策略模式、责任链模式

            在平时的开发中,涉及到设计模式的有两块内容,第一个是我们 平时使用的框架 (比如spring、mybatis等),第二个是我们自己开发业务使用的设计模式。         面试官一般比较关心的是你在开发过程中, 有没有使用过设计模式,或者你在简历上写了关于设计

    2024年02月10日
    浏览(56)
  • 【C++设计模式】详解装饰模式

    2023年8月31日,周四上午 这是我目前碰到的最难的设计模式..... 非常难以理解而且比较灵活多半,学得贼难受,写得贼费劲..... 2023年8月31日,周四晚上19:48 终于写完了,花了一天的时间来学习装饰模式和写这篇博客。 虽然基本上把我今天的收获都写下来了, 但感觉写得还是

    2024年02月10日
    浏览(31)
  • C++设计模式:装饰器模式(四)

    1、定义与动机 装饰器模式定义:动态(组合)地给一个对象增加一些额外的职责。就增加功能而言,Decorator模式比生成子类(继承)更为灵活(消除重复代码 减少子类个数)。 在某些情况下我们可能会“过度地使用继承来扩展对象的功能”,由于继承为类型引入的静态特质

    2024年04月11日
    浏览(30)
  • 【设计模式】Head First 设计模式——装饰者模式 C++实现

    设计模式最大的作用就是在变化和稳定中间寻找隔离点,然后分离它们,从而管理变化。将变化像小兔子一样关到笼子里,让它在笼子里随便跳,而不至于跳出来把你整个房间给污染掉。 动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

    2024年02月10日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包