惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
S
Schneier on Security
A
Arctic Wolf
Scott Helme
Scott Helme
S
Securelist
Schneier on Security
Schneier on Security
W
WeLiveSecurity
Attack and Defense Labs
Attack and Defense Labs
Security Latest
Security Latest
Project Zero
Project Zero
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Know Your Adversary
Know Your Adversary
P
Palo Alto Networks Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Google DeepMind News
Google DeepMind News
P
Proofpoint News Feed
C
Check Point Blog
F
Full Disclosure
Stack Overflow Blog
Stack Overflow Blog
H
Hacker News: Front Page
T
The Blog of Author Tim Ferriss
TaoSecurity Blog
TaoSecurity Blog
Vercel News
Vercel News
A
About on SuperTechFans
N
News and Events Feed by Topic
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
The GitHub Blog
The GitHub Blog
S
Security Affairs
Y
Y Combinator Blog
T
The Exploit Database - CXSecurity.com
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Forbes - Security
Forbes - Security
IT之家
IT之家
WordPress大学
WordPress大学
Last Week in AI
Last Week in AI
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
F
Fortinet All Blogs
N
Netflix TechBlog - Medium
The Register - Security
The Register - Security
Jina AI
Jina AI
云风的 BLOG
云风的 BLOG
T
Tailwind CSS Blog
K
Kaspersky official blog
Hacker News: Ask HN
Hacker News: Ask HN
C
Cisco Blogs
MyScale Blog
MyScale Blog
博客园 - 【当耐特】
T
Threat Research - Cisco Blogs
D
Docker
G
GRAHAM CLULEY

博客园 - wjwdive

如何使用git submodule拆分大的git项目 MAC多github账号配置步骤 记录一次flutter boost5.0.2示例调试的过程 【算法】可获得的最大点数问题 使用1panel一键建站 关于混合加密(AES+RSA) C++设计模式汇总 设计模式C++005__桥模式 设计模式C++007__抽象工厂方法模式 设计模式C++004__装饰器模式 设计模式C++003__观察者模式 设计模式C++001__模板方法 使用bundler自动化构建Xcode项目时遇到的问题。 AI图片生成网站 suno AI编曲创作利器 iOS组件化开发之私有库 iOS、Android获取apk公钥MD5信息 阿里图标库批量下载iOS适配的图标 C语言实现回调函数标准方式 swift 自定义tabbar为基本结构的项目 swift 可选类型
设计模式C++002__策略模式
wjwdive · 2024-07-25 · via 博客园 - wjwdive

设计模式C++002__策略模式

1、动机:

在软件构建过程中,某些对象使用的算法是多种多样的,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂;而且有时候支持不使用的算法也是一个性能负担。

?如何在运行时根据需要透明地更改对象的算法?将算法与对象本身解耦,从而避免上述问题?

2、策略模式:

定义一系列算法,把他们一个个封装起来,并且使他们可互相替换(变化)。该模式使得算法可以独立于使用它的客户程序(稳定)而变化(扩展,子类)。--GoF

例如跨国电商公司,订单计算税费的功能。
前期只有3个国家的业务,就只定义3个算法,使用枚举类区分。如果要在新的国家扩展业务。改动代码出如下,枚举定义处要改,还要在订单类里添加新的计算方法。
违反了开闭原则。

enum TaxBase {
	CN_Tax,
	US_Tax,
	DE_Tax,
	FR_Tax       //更改
};

class SalesOrder{
    TaxBase tax;
public:
    double CalculateTax(){
        //...
        
        if (tax == CN_Tax){
            //CN***********
        }
        else if (tax == US_Tax){
            //US***********
        }
        else if (tax == DE_Tax){
            //DE***********
        }
		else if (tax == FR_Tax){  //更改
			//...
		}

        //....
     }
    
};

如果使用策略模式,定义一个税费计算抽象基类,基类中只有一个计算税费的虚方法,不同国家的税费计算方法继承自抽象基类,各自实现自己的税费计算方法。
如果要支持新的税费计算方法,只需新建一个子类,根据实际情况实现即可。调用时利用C++的多态性质,在主函数中父类的指针指向子类对象,再用指针调用计算税费方法。
理论上,只要是if-else, switch-case 中可能会扩展新的分支以支持业务。都可以改为策略模式。

class TaxStrategy{
public:
    virtual double Calculate(const Context& context)=0;
    virtual ~TaxStrategy(){}
};


class CNTax : public TaxStrategy{
public:
    virtual double Calculate(const Context& context){
        //***********
    }
};

class USTax : public TaxStrategy{
public:
    virtual double Calculate(const Context& context){
        //***********
    }
};

class DETax : public TaxStrategy{
public:
    virtual double Calculate(const Context& context){
        //***********
    }
};



//扩展
//*********************************
class FRTax : public TaxStrategy{
public:
	virtual double Calculate(const Context& context){
		//.........
	}
};


class SalesOrder{
private:
    TaxStrategy* strategy;  //这里声明一个虚基类指针,访问类型为private

public:
    SalesOrder(StrategyFactory* strategyFactory){
        this->strategy = strategyFactory->New Strategy();//这里就是子类实例对象的产生的地方,可能是一个工厂方法产生的。
    }
    ~SalesOrder(){
        delete this->strategy;
    }

    public double CalculateTax(){
        //...
        Context context();
        
        double val = 
            strategy->Calculate(context); //多态调用
        //...
    }
    
};

3、策略模式相比 if-else这种分支处理。可以在不改变原有类的基础上,只新增子类,就可以实现对原有功能的扩展。符合开闭原则。

实际上,这也是利用了晚绑定的原理,调用哪一种方法。
结构:

4、要点总结:

  • Strategy及其子类为组提供了一些列可重用的算法,从而使得类型在运行时方便的根据需要再各个算法之间进行切换。
  • Strategy模式同了用条件判断语句以外的一种选择,消除条件判断语句,就是在解耦合。含有许多条件判断语句的代码通常都需要Strategy模式。
  • 如果Strategy对象没有实例变量,那么各个上下文可以共享同一个Strategy对象,从而节省对象开销。