【设计模式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();
}
相关推荐
雨中飘荡的记忆1 小时前
设计模式之享元模式详解
java·设计模式·享元模式
Blossom.1181 小时前
基于多智能体协作的AIGC内容风控系统:从单点检测到可解释裁决链
人工智能·python·深度学习·机器学习·设计模式·aigc·transformer
Jomurphys1 小时前
设计模式 - 责任链模式 Chain of Responsibility Pattern
android·设计模式·责任链模式
雨中飘荡的记忆2 小时前
设计模式之桥接模式详解
设计模式·桥接模式
雨中飘荡的记忆2 小时前
设计模式之访问者模式详解
设计模式·访问者模式
Jomurphys2 小时前
设计模式 - 享元模式 Flyweight Pattern
android·设计模式·享元模式
Jomurphys2 小时前
设计模式 - 组合模式 Composite Pattern
android·设计模式·组合模式
小杨快跑~16 小时前
从装饰者到桥接再到工厂:模式组合的艺术
java·开发语言·设计模式
海中有金17 小时前
设计模式[2]——抽象工厂模式一分钟说清
设计模式·抽象工厂模式