C++设计模式:策略模式

策略模式简述

在实际应用中,时常会遇到需要运行时判断执行具体算法的场景。这个时候,使用多个if else判断会让我们的代码显得很臃肿,灵活运用哈希表和策略模式会减少核心业务逻辑代码的规模,提高其可读性和可扩展性。

示例:分享给朋友功能

举个最常见的栗子,有篇文章写的很好,想分享给朋友,通常会出现多个选项:分享至微信好友,QQ好友,朋友圈等。简化的代码示意如下:

void share(const std::string& content, const std::string& shareType) {
	if (shareType == "wechat") {
		// 分享给微信好友
	} else if (shareType == "qq") {
		// 分享给QQ好友
	} else if ...
}

可以看出,这种实现方法的弊端在于:如果有多种社交软件,我们需要多行if else代码来判断。更可怕的是,如果将来新增或删除一种分享方式,需要深入到这个代码块去一个个找if statement做修改。

策略模式的实现

使用策略模式时,我们首先要抽象出一个通用的接口,也就是share。对于每一种社交软件,我们都实现一次这个接口,分别执行不同的任务。C++代码如下:

通用策略接口:
struct ShareStrategy {
    virtual void share(const std::string &content) = 0;
};
分享至微信好友策略:
struct WechatShareStrategy : ShareStrategy {
    void share(const std::string &content) override {
        std::cout << "Sharing to Wechat friend: " << content << std::endl;
    }
};
分享至QQ好友策略:
struct QQShareStrategy : ShareStrategy {
    void share(const std::string &content) override {
        std::cout << "Sharing to QQ friend: " << content << std::endl;
    }
};
用户类(Context)调用实现:
class User {
public:

    explicit User(std::shared_ptr<ShareStrategy> shareStrategy = nullptr) : shareStrategy(shareStrategy) {
    	// 初始化哈希表
        strategyMapper = {{"qq", std::make_shared<QQShareStrategy>()},
                          {"wechat",  std::make_shared<WechatShareStrategy>()}};
    }
	
	// 分享功能,调用策略对象所封装的方法
    void share(const std::string &content) {
    	// 曾经的if else在这里,现在只需要一行
        shareStrategy->share(content);
    }
	
	// 根据用户输入,查表选择应该调用的策略
    void resolveShareStrategy(const std::string &pattern) {
        shareStrategy = strategyMapper[pattern];
    }

private:
	// 当前所选择的策略
    std::shared_ptr<ShareStrategy> shareStrategy;
    // 存一个哈希表,用于根据用户输入而动态选择策略
    std::map<std::string, std::shared_ptr<ShareStrategy>> strategyMapper;
};
Demo用例实现:

用一个tuple来模拟用户请求,两个字段分别代表分享方法和内容。

int main() {
    User user;
    // C++17 structured binding
    const auto&[shareType, content] =  std::tuple<std::string, std::string>{
            "wechat",
            "Have a nice day."
    };
    // 确定分享策略
    user.resolveShareStrategy(shareType);
    // 分享内容
    user.share(content);
    // 改变一次分享策略
    user.resolveShareStrategy("qq");
    // 分享内容
    user.share(content);
}
输出
Sharing to Wechat friend: Have a nice day.
Sharing to QQ friend: Have a nice day.

结语

策略模式的好处在于扩展性良好,便于维护。想删除一个策略时只需要去除其实现类即可,而不再需要在茫茫if else海中寻找代码。同样地,想添加一个策略,也不需要在用户类的代码里寻找相应的方法。
其实,虽然看上去我们的核心业务代码少了很多if else,代码更清晰简洁。但也在无形中增添了很多策略的实现类。该少的代码一行少不了,只是换了个地方而已。所以,具体应该如何选择还是应该视核心代码的规模和策略的数量而定。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值