QT之策略模式【消除if else】

QT之策略模式【消除if else】



前言

策略模式即在运行时根据需求执行不同的方法。需要定义家族算法,通过多态重写同一个函数,可实现调用者的无感替换,不影响调用者。

策略模式把实现类和调用类实现了二者的分离,代码解耦。
策略模式提供了对开闭原则的完美支持。
策略模式依赖接口编程,同一接口支持多种实现方法。


一、策略模式基本实现

基类定义ExecTool方法,子类重写该方法,实现不同的功能逻辑。

class ToolBase : public QObject {
    Q_OBJECT
public:
    virtual bool ExecTool() { return true; }
};

定义子类工具A

class ToolA : public ToolBase {
    Q_OBJECT
public:
    bool ExecTool() override {
        qDebug() << "ToolA";
        return true;
    }
};

定义子类工具B

class ToolB : public ToolBase {
    Q_OBJECT
public:
    bool ExecTool() override {
        qDebug() << "ToolB";
        return true;
    }
};

根据策略执行不同的行为

int main(int argc, char *argv[])
{
    ToolBase* p = nullptr;
    QString str = "ToolA";
    if (str == "ToolA") {
        p = new ToolA();
    } else {
        p = new ToolB();
    }

    p->ExecTool();
    return 0;
}

二、问题点

如果目前需要新增一种工具, if else处要增加一个判断。那如果100个工具呢,1000个工具呢,代码将会非常臃肿,维护成本急剧增加。

三、进阶

增加工具注册类ToolRegiser.h文件,利用模板、函数指针和hash实现,使用前需要先调用REGISTER_TYPE宏注册工具子类。
调用类main.cpp只需要根据类名或者key值,即可创建工具子类,不再需要if else逻辑判断,代码相当简洁。

工具注册类【ToolRegister.h】

#define REGISTER_TYPE(ClassName) ToolRegister::registerTool<ClassName>();
class ToolRegister {
public:
    template <class T>
    static void registerTool() {
        creatorMap().insert(T::staticMetaObject.className(), &creatorHelper<T>);
    }

    static ToolBase* newInstance(const QString& className) {
        if (Creator creator = creatorMap().value(className)) {
            return (*creator)();
        }
        return nullptr;
    }

private:
    typedef ToolBase* (*Creator)();

    template <typename T>
    static ToolBase* creatorHelper() {
        return new T();
    }

    static QMap<QString, Creator>& creatorMap() {
        static QMap<QString, Creator> map;
        return map;
    }
};

调用类【main.cpp】

int main(int argc, char *argv[])
{
    //注册类
    REGISTER_TYPE(ToolA);
    REGISTER_TYPE(ToolB);

    QString str = "ToolA";
    if (ToolBase* p = ToolRegister::newInstance(str)) {
        p->ExecTool(); 
    }
    return 0;
}


总结

优化 => 枚举/字符串 + Hash + 函数指针 + 模板

如果大家在学习一个项目时,代码中有大量的if else判断,这可能由于设计之初没有考虑到业务需求的剧增,也可能随着维护时间越长,慢慢累积导致的。无论如何你应当重构这类代码,消除代码的坏味道,在日常编写代码的过程中即可完成代码重构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值