欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

策略模式

程序员文章站 2022-07-13 15:02:15
...

简介

在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的context 对象。策略对象改变context对象的执行算法。

  • 定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

角色

  • 抽象策略角色: 策略类,通常由一个接口或者抽象类实现。

  • 具体策略角色:包装了相关的算法和行为。

  • 环境角色:持有一个策略类的引用,最终给客户端调用。

图解

策略模式

应用场景

  • 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为.

  • 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。

  • 对客户隐藏具体策略(算法)的实现细节,彼此完全独立。

优点

  • 策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码转移到父类里面,从而避免重复的代码。

  • 策略模式提供了可以替换继承关系的办法。继承可以处理多种算法或行为。如果不是用策略模式,那么使用算法或行为的环境类就可能会有一些子类,每一个子类提供一个不同的算法或行为。但是,这样一来算法或行为的使用者就和算法或行为本身混在一起。决定使用哪一种算法或采取哪一种行为的逻辑就和算法或行为的逻辑混合在一起,从而不可能再独立演化。继承使得动态改变算法或行为变得不可能。

  • 使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重转移语句里面,比使用继承的办法还要原始和落后。

缺点

  • 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。

  • 策略模式造成很多的策略类,每个具体策略类都会产生一个新类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量。

实例

  • 我们出去旅游时会选择不同的交通工具:自行车,汽车自驾游、火车、飞机。我们会选择不同的出游策略:短游短时间选择自行车放松,稍微远一点的地方选择自驾游方便,距离远一点钱数有限选择火车,距离远钱多自然选择飞机。

  • strategy.h

#ifndef _STRATEGY_H_
#define _STRATEGY_H_


class Strategy
{
public:
    virtual void Travel() = 0;
};

#endif // _STRATEGY_H_
  • concrete_strategy.h
#ifndef _CONCRETE_STRATEGY_H_
#define _CONCRETE_STRATEGY_H_

#include "strategy.h"
#include <iostream>
#include<string>

using namespace std;

class BikeStrategy : public Strategy {
public:
    void Travel() {
        cout << "bike..." << endl; 
    }
};


class CarStrategy : public Strategy {
public:
    void Travel() { 
        cout << "car..." << endl; 
    }
};


class TrainStrategy : public Strategy {
public:
    void Travel() {
        cout << "train..." << endl;
    }
};

class PlaneStrategy : public Strategy {
public:
    void Travel() {
        cout << "plane..." << endl;
    }
};

#endif // _CONCRETE_STRATEGY_H_
  • context.h
#ifndef _CONTEXT_H_
#define _CONTEXT_H_

#include "strategy.h"

class Context
{
public:
    Context(Strategy *strategy):strategy(strategy){}
    ~Context(){
        if (strategy != nullptr) {
            delete strategy;
            strategy = nullptr;
        }
    }
    void Travel() {
        strategy->Travel(); 
    }

private:
    Strategy *strategy;
};

#endif // _CONTEXT_H_
  • main.cpp
#include "context.h"
#include "concrete_strategy.h"

int main(int argc,char* argv[]){
    Strategy *bike = new BikeStrategy();
    Context *context1 = new Context(bike);
    context1->Travel();

    Strategy *car = new CarStrategy();
    Context *context2 = new Context(car);
    context2->Travel();

    Strategy *plane = new PlaneStrategy();
    Context *context3 = new Context(plane);
    context3->Travel();

    //本来想的坐飞机,发现钱不够,改为火车
    Strategy *train = new TrainStrategy();
    context3 = new Context(train);
    context3->Travel();

    getchar();
    return 0;
}
  • 结果
    策略模式
相关标签: 策略模式