前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >策略模式虽好,Policy-based design更佳

策略模式虽好,Policy-based design更佳

作者头像
程序员的园
发布2024-07-18 13:21:39
980
发布2024-07-18 13:21:39
举报
文章被收录于专栏:程序员的园——原创文章

策略模式(设计模式——策略模式)大家耳熟能详,简言之,策略模式基于运虚表指针实现多态,但运行时的多态是有时间成本的。对于性能要求高的场景,策略模式反而不是最优选择。

Policy-based design(基于策略的设计)是一种现代C++编程中的高级泛型编程技术,基于模板或继承来定义一组可插拔的策略,每个策略代表一种特定的行为或特性。通过组合不同的策略,可以创建出具有不同功能特性的类实例,从而在不牺牲灵活性的前提下增加代码重用性和可扩展性。

与策略模式相比,策略模式侧重于在运行时动态切换行为,适用于OOP环境,主要通过对象组合和多态性实现。Policy-based Design则是在编译时期静态确定行为,适用于泛型编程环境,利用模板参数化实现行为的组合和选择,有助于提高代码的灵活性和重用性。

所以针对性能要求高且类似于策略模式的场景下时,推荐使用Policy-based design。

背景

假设有如下需求,某个酒店拥有自己的会员等级和会员制度,普通会员没有折扣;黄金会员享受9折优惠;钻石会员享受8折优惠;如何设计这套系统。(和策略模式的需求相同)

代码实现

Policy-based design 就可以基于模板实现,也可以基于继承实现,分别如下:

基于模板的实现方式

代码语言:javascript
复制
#include<concepts>

#include<iostream>


template <typenameT>

concept StrategyConcept = requires(T t, float arg) {

    {t.discont(arg)}-> std::same_as<float>;

};


template <typenameMemberType>

requires StrategyConcept<MemberType>

class MemberCart  {

public:

    float  check_out(floatnum) {
        MemberType t;
        returnt.discont(num);
    }
};


struct RegularMemberCart {
    floatdiscont(floatnum) {
      return num;
    }
};


struct GoldenMemberCart {

    floatdiscont(floatnum) {
        return num * 0.9;
    }
};



struct DiamondMemberCart {
    floatdiscont(floatnum) {
        return num * 0.8;
    }
};



int using_template() {

    MemberCart<RegularMemberCart> regular_cart;
    std::cout<<"regular member cost "<<regular_cart.check_out(100)<<std::endl;


    MemberCart<GoldenMemberCart> golden_cart;
    std::cout << "golden member cost " << golden_cart.check_out(100) << std::endl;


    MemberCart<DiamondMemberCart> diamond_cart;
    std::cout << "golden member cost " << diamond_cart.check_out(100) << std::endl;

    return 0;

}

基于继承的实现方式

代码语言:javascript
复制
#include<concepts>
#include<iostream>


template<typenameT>
structMemberCart:publicT
{
public:
    float
};


struct RegularMemberCart {
    floatdiscont(floatnum) {
        return num;
    }
};


struct GoldenMemberCart {
    floatdiscont(floatnum) {
        return num * 0.9;
    }
};


struct DiamondMemberCart {
    floatdiscont(floatnum) {
        return num * 0.8;
    }
};


int using_herb() {
    MemberCart<RegularMemberCart> regular_cart;
    std::cout << "regular member cost " << regular_cart.discont(100) << std::endl;


    MemberCart<GoldenMemberCart> golden_cart;
    std::cout << "golden member cost " << golden_cart.discont(100) << std::endl;


    MemberCart<DiamondMemberCart> diamond_cart;
    std::cout << "golden member cost " << diamond_cart.discont(100) << std::endl;
    return 0;
}

美玉存瑕

policy-based design 根据不同的策略选择不同的行为,不仅提供了灵活性,还具有很好的扩展性。有策略模式的地方就可以有Policy-based design,但是Policy-based design也存在其固有的缺点,

  • 编译器错误难以阅读和调试:当策略数量增加时,由于模板的组合爆炸性,编译器可能会生成大量的模板实例,导致编译时间显著增加,并可能产生难以理解和定位的错误信息。
  • 过度专业化:如果策略被滥用,可能会导致代码过于专业化,不利于通用性的保持,有时候过度设计反而不如简单直接的设计更容易理解和维护。
  • 缺乏运行时动态性:与策略模式不同,Policy-based Design在编译时就已经确定了策略,因此无法像策略模式那样在运行时动态地改变对象的行为。

总结

没有任何一种模式适用于所有场景,唯有适合的才是最好的。policy-based design虽好,切忌乱用,【当你手里拿着锤子,看什么都像是钉】不可取。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-03-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员的园 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档