首页 > 编程语言 >Qt C++设计模式->策略模式

Qt C++设计模式->策略模式

时间:2024-09-05 16:54:36浏览次数:7  
标签:Qt int C++ Strategy strategy 算法 设计模式 public 策略

**策略模式(Strategy Pattern)**是一种行为型设计模式,它定义了一系列算法,将每一个算法封装起来,并使它们可以互相替换,策略模式让算法可以独立于使用它的客户端而变化。这意味着,客户端可以根据需要动态选择使用哪种算法,而不需要修改算法的实现。

策略模式的主要组成部分

  1. 策略接口(Strategy Interface):定义了所有具体策略类需要实现的算法接口。
  2. 具体策略类(Concrete Strategy Classes):实现了策略接口中定义的算法。
  3. 上下文类(Context Class):维护对策略对象的引用,客户端通过上下文类与具体的策略对象进行交互,上下文类会将具体策略的实现委托给策略对象。

策略模式的优点

  • 可以动态地改变对象的行为,方便扩展新策略。
  • 避免了多重条件判断语句,算法或行为分离封装。

策略模式的缺点

  • 客户端必须了解所有策略,并自行决定使用哪一个策略。
  • 策略模式会增加类的数量。

策略模式的UML类图

  +---------------------+
  |       Context        |
  +---------------------+
  | - strategy: Strategy |
  +---------------------+
  | + setStrategy(Strategy): void |
  | + executeStrategy(): void     |
  +---------------------+
              |
              |
    +-----------------+
    |     Strategy     | <--- 抽象接口
    +-----------------+
    | + algorithm(): void |
    +-----------------+
        /      |     \
       /       |      \
  +---------+  +---------+  +---------+
  | Concrete|  | Concrete|  | Concrete|
  |Strategy1|  |Strategy2|  |Strategy3|
  +---------+  +---------+  +---------+

策略模式示例:Qt C++ 小Demo

我们将构建一个简单的示例,展示如何使用策略模式选择不同的算法来执行计算。在这个例子中,我们使用策略模式来实现不同的数学运算策略,如加法、减法和乘法。

1. 定义策略接口(Strategy Interface)

首先定义一个策略接口,声明不同运算需要实现的算法接口:

class Strategy {
public:
    virtual ~Strategy() {}
    virtual int execute(int a, int b) = 0;
};

2. 实现具体策略类(Concrete Strategy Classes)

然后,我们实现具体的策略类,如加法、减法和乘法:

class AddStrategy : public Strategy {
public:
    int execute(int a, int b) override {
        return a + b;
    }
};

class SubtractStrategy : public Strategy {
public:
    int execute(int a, int b) override {
        return a - b;
    }
};

class MultiplyStrategy : public Strategy {
public:
    int execute(int a, int b) override {
        return a * b;
    }
};

3. 上下文类(Context Class)

上下文类持有一个策略的引用,并且可以在运行时动态地改变策略:

class Context {
private:
    Strategy* strategy;

public:
    Context(Strategy* strategy = nullptr) : strategy(strategy) {}

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

    int executeStrategy(int a, int b) {
        if (strategy)
            return strategy->execute(a, b);
        return 0; // 默认返回值
    }
};

4. 使用策略模式

现在我们可以编写客户端代码,动态选择不同的策略来执行计算:

#include <iostream>

int main() {
    Context context;

    // 设置为加法策略
    AddStrategy addStrategy;
    context.setStrategy(&addStrategy);
    std::cout << "5 + 3 = " << context.executeStrategy(5, 3) << std::endl;

    // 设置为减法策略
    SubtractStrategy subtractStrategy;
    context.setStrategy(&subtractStrategy);
    std::cout << "5 - 3 = " << context.executeStrategy(5, 3) << std::endl;

    // 设置为乘法策略
    MultiplyStrategy multiplyStrategy;
    context.setStrategy(&multiplyStrategy);
    std::cout << "5 * 3 = " << context.executeStrategy(5, 3) << std::endl;

    return 0;
}

输出结果:

5 + 3 = 8
5 - 3 = 2
5 * 3 = 15

关键点

  • 上下文类Context负责维护策略,并可以动态更改策略。
  • 每个具体的策略类实现了不同的算法(加法、减法、乘法)。
  • 通过策略模式,客户端可以方便地替换策略,而不需要修改上下文类的代码

总结

策略模式通过将不同的算法封装为独立的类,便于在运行时动态替换这些算法。在Qt C++开发中,策略模式可用于需要灵活切换算法或行为的场景,例如不同的绘图引擎、数据处理策略等。

标签:Qt,int,C++,Strategy,strategy,算法,设计模式,public,策略
From: https://blog.csdn.net/m0_46494667/article/details/141935049

相关文章

  • C++ STL stack容器——栈
    stack容器基本概念stack是一种先进后出的数据结构,它只有一个出口,形式如下图所示。stack容器允许新增元素,移除元素,取得栈顶元素,但是除了最顶端外,没有任何地方可以存取stack的娶她元素。换句话说,stack不允许有遍历行为。元素推入栈的操作称为push,将元素推出栈的操作称为pop。st......
  • C++程序的发布部署方式及缺失依赖库dll的解决方法
    主要对Windows平台上C++项目开发过程中库目录进行梳理及程序发布要注意的相关事项进行总结,希望对其他开发者有一定的借鉴意义。1.问题的提出在最近的项目中,主要工作是为SketcchUp平台开发基于Ruby的扩展功能库,这种库文件是以.so为后缀的形式提供,用C++语言来编写实现。当我在自己......
  • C++ 使用终端GDB调试复杂项目中Segmentation Fault 和 std::bad_alloc问题
            近期在公司虚拟机上写代码遇到SegmentationFault和std::bad_alloc问题,但是项目庞大,在不了解功能、代码连接关系的时候很难追踪具体是什么地方出了问题。网络上许多关于GDB的教程仅仅停留在简单的示例中的调试,对于复杂的项目结构(多文件,多作用域,......)来说显......
  • C++(for)
    目录1.经典的for循环2.基于范围的for循环(C++11引入)3.无限for循环4.嵌套for循环5.使用continue和break控制循环流总结C++中有多种形式的for循环,每种形式适合不同的应用场景。1.经典的for循环这是C++中最基础的循环类型,由三部分组成:初始化、条件、......
  • C++ 模板(函数模板)
    模板模板介绍C++提供了函数模板(functiontemplate)。所谓函数模板。实际上是建立一个通用函数,其函数类型和形参类型不具体制定,用一个虚拟的类型来代表。这个通用函数就称为函数模板。凡事函数体相同的函数都可以使用这个模板代替,不必定义多个函数,只需在模板中定义一次即可。在调......
  • QT6编写外部库并调用
    步骤创建qt项目,项目类型选择库。注意,在创建项目的过程中:在Details页面的QTmodule处,需要选择使用Core、Gui还是Widgets。如果不需要界面就选择Core,如果需要Gui或Widget就选择对应的即可。创建完成项目后,编写项目内容。编写完毕后点击构建(注意不是Debug或Release是Build)。如......
  • C++: std::once_flag 和 std::call_once
    std::once_flag和std::call_oncestd::once_flag和std::call_once是C++11引入的同步原语,用于确保某个函数在多线程环境中只被执行一次。它们位于头文件中,主要用于实现线程安全的初始化操作。std::once_flag概述类型:std::once_flag是一个结构体,用于记录某个函数......
  • C++ 原子变量atomic variable
    原子变量原子变量(atomicvariable)是C++11引入的一种同步机制,用于在多线程环境中进行无锁的、线程安全的操作。原子变量的操作是不可分割的,即在执行过程中不会被其他线程中断,从而避免了数据竞争和不一致的问题。原子变量位于头文件中。基本概念原子性原子性:一个操作是......
  • C++和Python混合编程——C++调用Python入门
    大纲代码结构初始化Python解释器获取GIL为什么需要GIL?GIL的影响导入Python模块并执行代码释放GIL终止Python解释器完整代码编译执行结果项目地址在《C++和Python混合编程——Python调用C++入门》一文中,我们熟悉了Python调用C++编译的动态库的方法。但是作......
  • C++11新特性
    C++11主要新特性有类的初始化与函数、新增关键字、std库新特性、lambda表达式、智能指针、线程1.关键字()nullptr取代NULL、0()constexpr:显式声明函数返回值、变量是一个常量表达式()auto:对变量类型推导,()decltype:对表达式类型推导,用法为decltype(表达式)()using:声明使用的命......