【设计模式02】策略设计模式(行为型设计模式)

设计模式相当于说明书

1. 策略模式

英雄使用不同的武器,需要进行武器切换。

使用多态,运行时切换对象内的算法。可将算法的实现和使用算法的代码隔离开。可以组合来代替继承。开闭原则。无需对上下文进行修改就能引入新的策略

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;
//Strategy
class Weapon {
public:
    virtual string fightAlgorithm() const = 0;
};

class Nife : public Weapon {
public:
    string fightAlgorithm() const override {
        return "Calculating damage using a dagger.";
    }
};
class Axe : public Weapon {
public:
    string fightAlgorithm() const override {
        return "Calculating damage using an axe.";
    }
};

//Context
class Hero {
private:
    Weapon* m_weapon;  // 抽象类指针指向实现类对象
public:
    Hero(Weapon* weapon = nullptr) :m_weapon(weapon) {}
    void setWeapon(Weapon* weapon) { m_weapon = weapon; }

    void fight() {
        cout << m_weapon->fightAlgorithm() << "\n";
    }
};

int main()
{
    cout << "Client: Hero attacks with a dagger.\n";
    Nife nife;
    Hero hero(&nife);
    hero.fight();
    cout << "Client: Hero attacks with an axe.\n";
    Axe axe;
    hero.setWeapon(&axe);
    hero.fight();
}

2.策略模式在Qt中的使用

将策略抽象出来,来实现不同的过滤条件类。不同的过滤条件类交给同一个代理进行操作。实现按照条件进行过滤的功能。按照条件查找对应的人和对象

实现思路

1.创建一个模型QStandardItemModel,将数据添加到模型中

2.新建一个模型过滤代理类FilterStrategy,将模型添加到模型过滤代理类,过滤代理类是抽象类通过不同的类来进行继承和扩展。


cpp 复制代码
#include <QApplication>
#include <QTreeView>
#include <QStandardItemModel>
#include <QSortFilterProxyModel>
#include <QVBoxLayout>
#include <QComboBox>
#include <QWidget>

// 自定义过滤策略
class FilterStrategy {
public:
    virtual ~FilterStrategy() = default;
    virtual bool filterAcceptsRow(const QModelIndex& sourceIndex, const QAbstractItemModel* sourceModel) const = 0;
};

// 按名称过滤
class NameFilterStrategy : public FilterStrategy {
public:
    bool filterAcceptsRow(const QModelIndex& sourceIndex, const QAbstractItemModel* sourceModel) const override {
        QString name = sourceModel->data(sourceIndex.siblingAtColumn(0)).toString();  // 0拿到字符串
        return name.contains("A", Qt::CaseInsensitive);
    }
};
// 按年龄过滤
class AgeFilterStrategy : public FilterStrategy {
public:
    bool filterAcceptsRow(const QModelIndex& sourceIndex, const QAbstractItemModel* sourceModel) const override {
        int age = sourceModel->data(sourceIndex.siblingAtColumn(1)).toInt();  // 1拿到姓名
        return age > 25;
    }
};

// 自定义代理模型
class StrategyProxyModel : public QSortFilterProxyModel {
public:
    void setFilterStrategy(FilterStrategy* strategy) {
        m_strategy.reset(strategy);
        invalidateFilter();
    }
protected:
    bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override {
        if (!m_strategy) return true;  // 如果为空则返回,如果不为空则继续执行
        // 获取到这个module里面这个数据要不要显示出来
        
        QModelIndex index0 = sourceModel()->index(sourceRow, 0, sourceParent);
        
        return m_strategy->filterAcceptsRow(index0, sourceModel());
    }
private:
	// 依赖于抽象策略
    QScopedPointer<FilterStrategy> m_strategy;
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    // 创建数据模型(只有Name和Age两列)
    QStandardItemModel model;
    model.setHorizontalHeaderLabels({"Name", "Age"});
    model.appendRow({new QStandardItem("Alice"), new QStandardItem("25")});
    model.appendRow({new QStandardItem("Bob"), new QStandardItem("30")});
    model.appendRow({new QStandardItem("Charlie"), new QStandardItem("22")});
    model.appendRow({new QStandardItem("David"), new QStandardItem("28")});

    // 创建代理模型
    StrategyProxyModel proxyModel;
    proxyModel.setSourceModel(&model);

    QWidget window;
    QVBoxLayout layout(&window);
    QComboBox filterCombo;
    QTreeView treeView;
    treeView.setModel(&proxyModel);
    filterCombo.addItems({"All", "Name contains A", "Age > 25"});

    layout.addWidget(&filterCombo);
    layout.addWidget(&treeView);
    window.resize(300, 250);

    // 连接策略切换
    QObject::connect(&filterCombo, &QComboBox::currentTextChanged, [&](const QString& text) {
        if (text == "Name contains A") return proxyModel.setFilterStrategy(new NameFilterStrategy());
        if (text == "Age > 25") return proxyModel.setFilterStrategy(new AgeFilterStrategy());
        return proxyModel.setFilterStrategy(nullptr);
    });
    window.show();
    return a.exec();
}
相关推荐
geovindu9 小时前
python: Broadcast Pattern
开发语言·python·设计模式·广播模式
我爱cope9 小时前
【Agent智能体22 | 构建AI工作流的技巧-延迟、成本优化】
人工智能·设计模式·语言模型·职场和发展
guslegend10 小时前
第1章:从结构到智能,设计模式的世纪旅程
设计模式
我爱cope10 小时前
【Agent智能体21 | 构建AI工作流的技巧-优化组件的常用方法】
人工智能·设计模式·语言模型·职场和发展
小bo波20 小时前
枚举实战
java·设计模式·枚举·后端开发·代码重构
不好听6131 天前
Prompt 驱动 NLP:用大语言模型重新定义自然语言处理开发范式
设计模式·node.js·nlp
天文家1 天前
深入理解装饰器与适配器:从设计模式到 Spring AOP 的工程实践
java·设计模式
workflower1 天前
医院核心竞争力的四大重构
人工智能·安全·设计模式·重构·动态规划·scrum
折哥的程序人生 · 物流技术专研1 天前
【电商多平台电子面单对接实战|第二篇】抖音代发电子面单对接:从“面条代码”到整洁架构的涅槃之路
设计模式·架构·系统架构·单元测试·代码规范·单一职责原则
葫芦和十三1 天前
范式之变|Agent 设计,换语言了
人工智能·设计模式