C++之策略模式

策略模式的定义:

策略模式是指定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。

优点:1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。

缺点:1、策略类会增多。 2、所有策略类都需要对外暴露。

类图如下

C++之策略模式

Strategy: 抽象策略类,定义抽象的函数算法让继承的子类实现。

ConcreteStrategy:封装了继续相关的算法和行为,即函数的具体功能的实现

Context:持有一个策略类的引用,最终给客户端调用。

我认为策略模式的重点在于context类的定义,这也是策略模式与模板模式最大的不同,即通过对策略基类Strategy的组合出的类context,根据子类的不同,灵活地通过类context中的多态指针调用来实现一系列子类算法,也叫根据不同策略执行不同的行为。策略由外部环境决定

总结起来就是Context 指向 Strategy (由指针实现);Context 通过 Strategy 接口,调用一系列算法;ConcreteStrategy 实现了一系列具体的算法

下面举一个例子来说明策略模式的好处:

假如一个跨国公司A在多个国家有分公司,且在不同国家的经营模式根据国家国情会有所不同,而且分公司负责人也不同,要求编写程序实现这一情况的描述。首先容易想到的是定义一个基类,然后针对不同的分公司用switch语句进行选择来编写。代码如下:

1

include

using namespace std;

class Company

{

private:

string name;

int type;

public:

Company(string n,int t)

{

name=n;

type=t;

}

void printcompany()

{

switch(type)

{

case 1:

cout<<"负责人"<<name<<endl;

China();

break;

case 2:

cout<<"负责人"<<name<<endl;

America();

break;

case 3:

cout<<"负责人"<<name<<endl;

France();

break;

}

}

void China()

{

cout<<"中国分公司:经营模式1的具体实现..."<<endl;

}

void America()

{

cout<<"美国分公司:经营模式2的具体实现..."<<endl;

}

void France()

{

cout<<"法国分公司:经营模式3的实现..."<<endl;

}

};

int main()

{

Company a1("张三",1);

Company a2("李四",2);

Company a3("王五",3);

a1.printcompany();

cout<<"================================================="<<endl;

a2.printcompany();

cout<<"================================================="<<endl;

a3.printcompany();

}

然而这个程序只是最简单的做法,其扩展性并不好,例如要在印度一个新分公司,需要在类添加相关公司经营模式函数,也要在switch添加相关公司内容,如果某个分公司的经营模式要改变,也要通过去类中寻找相应的函数去修改,但如果分公司多了,类就会变得很臃肿且不方便查找修改。如果我们采用策略模式,把函数定义写在抽象基类中,把每个分公司写成一个继承子类,由不同的算法实现不同经营模式,然后再写一个封装的context类来实现客户端调用,这样就可以一目了然了,建立分公司和修改信息就只需要对子类进行操作,基类并不需要任何修改,而且通过contex类提供的接口可以很方便的选择展示不同公司的情况,代码如下:

#include <iostream>

using namespace std;

class Company

{

public:

    string name;

    virtual void Management()=0;

};

class Company1:public Company

{

public:

    Company1(string n)

    {
        name=n;

    }

    void printcompany()

    {

        cout<<"负责人"<<name<<endl;

    }

    virtual void Management()

    {

        cout<<"中国分公司:经营模式1的具体实现..."<<endl;

    }

};

class Company2:public Company

{

public:

    Company2(string n)

    {

        name=n;

    }

    void printcompany()

    {

        cout<<"负责人"<<name<<endl;

    }

    virtual void Management()

    {

        cout<<"美国分公司:经营模式2的具体实现..."<<endl;

    }

};

class Company3:public Company

{

public:

    Company3(string n)

    {

        name=n;

    }

    void printcompany()

    {

        cout<<"负责人"<<name<<endl;

    }

    virtual void Management()

    {

        cout<<"法国分公司:经营模式3的实现..."<<endl;

    }

};

class Context

{

public:

    Company *com;

    Context(Company *c)

    {

        com=c;

    }

    void printcompany()

    {

        com->Management();

    }

};

int main()

{

    Company *china=new Company1("张三");

    Company *america=new Company2("张三");

    Company *france=new Company3("张三");

    Context a1(china);

    Context a2(america);

    Context a3(france);

    a1.printcompany();

    cout<<"================================================="<<endl;

    a2.printcompany();

    cout<<"================================================="<<endl;

    a3.printcompany();

}

从设计模式的角度来说,这种模式隔离变化,编程到接口,有新公司加入,只要写一个子类就可以,不需要改变其他类的代码,所以其他的类都是稳定的,这就体现了我们策略模式的设计原则和目的。

原文链接: https://www.cnblogs.com/xiaxiaopi/p/12470548.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/194251

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月12日 下午6:38
下一篇 2023年2月12日 下午6:38

相关推荐