Linux C++ 046-设计模式之策略模式

Linux C++ 046-设计模式之策略模式

本节关键字:Linux、C++、设计模式、策略模式
相关库函数:

概念

策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。(原文:The Strategy Pattern defines a family of algorithms,encapsulates each one,and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.)
 
Context(应用场景):
1、需要使用ConcreteStrategy提供的算法。
2、 内部维护一个Strategy的实例。
3、 负责动态设置运行时Strategy具体的实现算法。
4、负责跟Strategy之间的交互和数据传递。

Strategy(抽象策略类):
1、 定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,Context使用这个接口调用不同的算法,一般使用接口或 抽象类实现。

ConcreteStrategy(具体策略类):
1、 实现了Strategy定义的接口,提供具体的算法实现。

应用场景

1、 多个类只区别在 表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。(例如FlyBehavior和QuackBehavior)

2、 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。(例如FlyBehavior和QuackBehavior的具体实现可任意变化或扩充)

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

优缺点

优点:
1、 提供了一种替代继承的方法,而且既保持了继承的优点(代码重用)还比继承更灵活(算法独立,可以任意扩展)。
2、 避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展。
3、 遵守大部分GRASP原则和常用设计原则, 高内聚、低偶合。

缺点:
1、 因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量。

代码示例
class CashSuper
{
public:
    virtual double acceptMoney(double money) = 0;
};
// 策略类1
class CashNormal : public CashSuper
{
public:
    double acceptMoney(double money) {
        return money;
    }
};
// 策略类2
class CashRebate : public CashSuper
{
private:
    double discount;
public:
    CashRebate(double dis) {
        discount = dis;
    }
    double acceptMoney(double money) {
        return money * discount;
    }
};
// 策略类3
class CashReturn : public CashSuper
{
private:
    double moneyCondition;
    double moneyReturn;
public:
    CashReturn(double mc, double mr) {
        moneyCondition = mc;
        moneyReturn = mr;
    }
    double accoptMoney(double money) {
        double result = money;
        if (money >= moneyCondition) {
            result = money - floor(money / moneyCondition) * moneyReturn;
        }
        return result;
    }
};
// 上下文
class CashContext
{
private:
    CashSuper* cs;
public:
    CashContext(CashSuper* cs) { // 维护一个对策略对象的引用
        this->cs = cs;
    }
    double getResult(double money) { // 调用相应的算法
        return cs->acceptMoney(money);
    }
};

// 上述代码中相当于定义了3种策略,从策略基类派生出3种策略派生类
// 上下文类:定义了一个策略基类类型的成员变量,定义了调用策略派生类种算法的成员函数
// 客户端:需要知道上下文类和策略类,创建策略对象,借助上下文对象调用不同的算法
int main_Cash()
{
    CashSuper* cs;
    CashContext* cc;
    double money;

    money = 1000;
    cs = new CashRebate(0.8);
    cc = new CashContext(cs);
    cout << cc->getResult(money) << endl;

    money = 1000;
    cs = new CashNormal();
    cc = new CashContext(cs);
    cout << cc->getResult(money) << endl;
    return 0;
}
策略模式和简单工厂模式组合



// 策略模式和简单工厂模式相结合
// 优点:客户端只需访问上下文类,而不需要知道其他的信息,实现了低耦合
#include <cmath>
class CashSuper2
{
public:
    virtual double acceptMoney(double money) = 0;
};
// 策略类1
class CashNormal2 : public CashSuper2
{
public:
    double acceptMoney(double money) {
        return money;
    }
};
// 策略类2
class CashRebate2 : public CashSuper2
{
private:
    double discount;
public:
    CashRebate2(double dis) {
        discount = dis;
    }
    double acceptMoney(double money) {
        return money * discount;
    }
};
// 策略类3
class CashReturn2 : public CashSuper2
{
private:
    double moneyCondition;
    double moneyReturn;
public:
    CashReturn2(double mc, double mr) {
        moneyCondition = mc;
        moneyReturn = mr;
    }
    double acceptMoney(double money) {
        double result = money;
        if (money >= moneyCondition) {
            result = money - floor(money / moneyCondition) * moneyReturn;
        }
        return result;
    }
};
// 上下文
class CashContext2
{
private:
    CashSuper2* cs;
public:
    CashContext2(string str) {
        if (str == "正常收费") {
            cs = new CashNormal2();
        }
        else if (str == "打9折") {
            cs = new CashRebate2(0.9);
        }
        else if (str == "满300送200") {
            cs = new CashReturn2(300, 200);
        }
        else {
            cs = NULL;
        }
    }
    double getResult(double money) { // 调用相应的算法
        return cs->acceptMoney(money);
    }
};
// 策略派生类和策略模式的相同,有一个策略基类,派生了3个策略类。区别在于上下文类
// 上下文类:定义了一个策略基类的对象,在策略基类的对象中来决定实例化哪种策略对象(区别于策略模式),定义一个成员函数,调用策略中定义个算法
// 客户端:自需要知晓上下文类即可。只需创建上下文类的对象,调用该类中的方法即可获得结果
int main_FectoryAndCash()
{
    double money = 1000;
    CashContext2* cc = new CashContext2("打9折");
    cout << cc->getResult(money) << endl;
    return 0;
}

相关推荐

  1. Linux C++ 046-设计模式策略模式

    2024-07-09 23:16:07       24 阅读
  2. 设计模式策略模式

    2024-07-09 23:16:07       47 阅读
  3. 设计模式策略模式

    2024-07-09 23:16:07       52 阅读
  4. 设计模式策略模式

    2024-07-09 23:16:07       39 阅读
  5. 设计模式策略模式

    2024-07-09 23:16:07       34 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-09 23:16:07       50 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-09 23:16:07       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-09 23:16:07       43 阅读
  4. Python语言-面向对象

    2024-07-09 23:16:07       54 阅读

热门阅读

  1. 2024年二级建造师考试题库及答案

    2024-07-09 23:16:07       24 阅读
  2. 深入解析Spring Boot的application.yml配置文件

    2024-07-09 23:16:07       23 阅读
  3. Docker技术简介

    2024-07-09 23:16:07       19 阅读
  4. Qt 的 qmake的语法简介与例子介绍

    2024-07-09 23:16:07       22 阅读
  5. C#用链表和数组分别实现堆栈

    2024-07-09 23:16:07       21 阅读
  6. Go bytes包

    2024-07-09 23:16:07       24 阅读
  7. C#面 :ASP.Net Core中有哪些异常处理的方案?

    2024-07-09 23:16:07       21 阅读