设计模式-策略模式

策略模式

  1. 定义
    • 定义一系列的算法,把他们封装起来,并且使它们可以相互替换。该模式使得算法可独立于使用它们的客户而变化。
  2. 实现描述
    • 使用的客户类中包含算法的抽象类,算法的具体实现类则继承抽象类并且具体实现算法接口,将算法的抽象类作为使用的客户类的构造参数,在客户类构造时传入。客户类在之后使用不同算法可以直接调用不同的算法类。

UML 类图

时序图

使用场景

  1. 存在以下场景使用策略模式
    • 许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法
    • 需要使用一个算法的不同变种
    • 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构
    • 一个类定义了多种行为,并且这种行为在这个类的操作中以多个语句的形式出现。

优缺点

代码实现

  • 策略模式(单独)
// 摘自大话设计模式
#include<iostream>
using namespace std;

// 抽象收费策略
class CashSuper
{
private:
    /* data */
public:
    virtual double acceptCash(double) = 0;
};

// 正常收费类
class CashNornal: public CashSuper{
public:
    virtual double acceptCash(double money){
        return money;
    }
};

// 打折收费类
class CashRebate : public CashSuper {
public:
    CashRebate(double money_rebate) {
        mMoneyRebate = money_rebate;
    }

    virtual double acceptCash(double money) {
        return money * mMoneyRebate;
    }
private:
    double mMoneyRebate = 1.0;
};

// 返利收费类
class CashReturn : public CashSuper {
public:
    CashReturn(double money_condition, double money_return) {
        mMoneyCondition = money_condition;
        mMoneyReturn = money_return;
    }

    virtual double acceptCash(double money){
        double result = money;
        if(money >= mMoneyCondition) {
            result = money - (int)(money / mMoneyCondition) * mMoneyReturn;
            return result;
        }
        return result;
    }
private:
    double mMoneyCondition = 0;
    double mMoneyReturn = 0;
};

class CashContext{
public:
    CashContext(CashSuper* pCashSuper){
        mPCashSuper = pCashSuper;
    }
    
    double ContextInterface(double money){
        return mPCashSuper->acceptCash(money);
    }

    ~CashContext(){
        if(this->mPCashSuper != nullptr){
            delete mPCashSuper;
        }
    }
public:
    CashSuper* mPCashSuper = nullptr;
};

int main()
{
    CashContext* context = NULL;
    context = new CashContext(new CashNornal());
    cout << "cahsNormal : " << context->ContextInterface(700) << endl;

    context = new CashContext(new CashRebate(0.8));
    cout << "CashRebate : " << context->ContextInterface(700) << endl;

    context = new CashContext(new CashReturn(300,100));
    cout << "CashRebate : " << context->ContextInterface(700) << endl;

    return 0;
}
  • 策略模式+简单工厂模式
// 摘自网络(https://www.cnblogs.com/ring1992/p/9593575.html)
typedef enum StrategyType{
    StrategyA,
    StrategyB,
    StrategyC
}STRATEGYTYPE;

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

Strategy::~Strategy(){}

class ConcreteStrategyA : public Strategy
{
public:
    void AlgorithmInterface(){
        cout << "I am from ConcreteStrategyA." << endl;
    }
    ~ConcreteStrategyA(){}
};

class ConcreteStrategyB : public Strategy
{
public:
    void AlgorithmInterface(){
        cout << "I am from ConcreteStrategyB." << endl;
    }
    ~ConcreteStrategyB(){}
};

class ConcreteStrategyC : public Strategy
{
public:
    void AlgorithmInterface(){
        cout << "I am from ConcreteStrategyC." << endl;
    }
    ~ConcreteStrategyC(){}
};

class Context
{
public:
    Context(STRATEGYTYPE enum_strategy_type){
        switch (enum_strategy_type)
        {
        case StrategyA:
            pStrategy = new ConcreteStrategyA;
            break;
        case StrategyB:
            pStrategy = new ConcreteStrategyB;
            break;
        case StrategyC:
            pStrategy = new ConcreteStrategyC;
            break;
        default:
            break;
        }
    }
    ~Context(){
        if(pStrategy){
            delete pStrategy;
            pStrategy = NULL;
        }
    }
    void callAlgorithm(){
        if(pStrategy){
            pStrategy->AlgorithmInterface();
        }
    }
private:
    Strategy* pStrategy;
};

int main()
{
    Context *pContext = new Context(StrategyA);
    pContext->callAlgorithm();
    return 0;
}

总结

posted @ 2023-03-27 11:06  王清河  阅读(20)  评论(0编辑  收藏  举报