设计模式 -- 策略模式 -- c++实现

注:本文主要代码基于大话设计模式里的C#代码(第2章)。

 

UML图:

 

策略模式的实现:

将所要用的所有算法抽象出一个接口(所以每个算法要用类实现)

使用一个策略上下文类,封装一个算法接口的指针,并提供一个函数给外部调用具体算法。

外部用具体算法类的指针来创建策略上下文类。


下面代码是一个商场收费系统的抽象,将收费的算法(普通,打折,返利)抽象成cCashSuper接口

在策略上下文类cCashContext中使用工厂模式,可以将具体算法的调用与调用者解耦。


代码如下:

/*****************************************************
* 模式名:策略模式
* 时间:2010.6.3
*                                       -by gouki04
*****************************************************/

#pragma once

//
class cCashContext;         // (策略上下文类,封装了一个策略接口的指针)
class cCashContext_Factory; // (策略上下文类与简单工厂模式结合)
class cCashSuper;           // 收费类接口(策略接口,定义所有算法的公共接口)
class cCashNormal;          // 普通收费类(基本策略类)
class cCashRebate;          // 打折收费类(基本策略类)
class cCashReturn;          // 返利收费类(基本策略类)
//

// 收费类接口(策略接口,定义所有算法的公共接口)
class cCashSuper
{
public:
    // 收费方法
    // 参数:money为原收费
    // 返回:应收费
    virtual double AcceptCash(double money) = 0;
};

// 普通收费类(基本策略类)
class cCashNormal : public cCashSuper
{
public:
    double AcceptCash(double money) { return money; }
};

// 打折收费类(基本策略类)
class cCashRebate : public cCashSuper
{
private:
    double m_moneyRebate; // 折扣率

public:
    cCashRebate(double rebate = 1.0) : m_moneyRebate(rebate) {}
    double AcceptCash(double money) { return money * m_moneyRebate; }
};

// 返利收费类(基本策略类)
// 例:满300返100
class cCashReturn : public cCashSuper
{
private:
    double m_moneyCondition; // 返还条件的金钱数
    double m_moneyReturn;  // 返还的金钱数

public:
    cCashReturn(double condition = 0.0, double _return = 0.0) : m_moneyCondition(condition), m_moneyReturn(_return) {}
    double AcceptCash(double money)
    {
        if (money > m_moneyCondition)
            money -= static_cast<int>(money / m_moneyCondition) * m_moneyReturn;
        return money;
    }
};

// (策略上下文类,封装了一个策略接口的指针)
class cCashContext
{
private:
    cCashSuper * m_pCashSuper;

public:
    cCashContext(cCashSuper* cs) : m_pCashSuper(cs) {}
    virtual ~cCashContext() { /* 这里没有必要析构m_pCashSuper,因为它是外部引入,应该由外部负责析构 */ }

    // 调用具体的收费算法
    double AcceptCash(double money) { return m_pCashSuper->AcceptCash(money); }
};

// 策略上下文类与简单工厂模式结合
// 将具体的选择算法的过程封装起来
class cCashContext_Factory
{
private:
    cCashSuper * m_pCashSuper;

public:
    // 此处的构造函数体应该放在cpp文件中,这里为了方便阅读而改为内联函数
    // 像switch这样的语句不应该使用内联
    cCashContext_Factory(int type = 0)
    {
        switch (type) {
        case 0:
            m_pCashSuper = new cCashNormal();
            break;
        case 1:
            m_pCashSuper = new cCashRebate(0.8);
            break;
        case 2:
            m_pCashSuper = new cCashReturn(300, 100);
            break;
        default:
            throw type;
        }
    }
    virtual ~cCashContext_Factory() { if (m_pCashSuper) delete m_pCashSuper; }

    // 调用具体的收费算法
    double AcceptCash(double money) { return m_pCashSuper->AcceptCash(money); }
};

// 测试的main函数 
//int main()
//{
//    using namespace std;
//
//    cCashContext* pContext = NULL;
//    cCashSuper* pCashSuper = NULL;
//    try {
//        int type = 0;
//        cout << "0 --> 普通收费" << endl << "1 --> 打8折" << endl << "2 --> 满300返100" << endl << "请选择收费方式:";
//        cin >> type;
//
//        switch (type) {
//        case 0:
//            pCashSuper = new cCashNormal();
//            break;
//        case 1:
//            pCashSuper = new cCashRebate(0.8);
//            break;
//        case 2:
//            pCashSuper = new cCashReturn(300, 100);
//            break;
//        default:
//            throw type;
//        }
//        pContext = new cCashContext(pCashSuper);
//
//        cout << endl << "总费用为:";
//        double totalPrice = 0;
//        cin >> totalPrice;
//
//        cout << endl << "应收费为:" << pContext->AcceptCash(totalPrice) << endl;
//    }
//    catch (int type) {
//        cout << "没有" << type << "这种收费方式。" << endl;
//    }
//    catch (...) {
//        cout << "输入错误" << endl;
//    }
//
//    if (pContext)
//        delete pContext;
//
//    if (pCashSuper)
//        delete pCashSuper;
//
//    return 0;
//}

// 使用策略模式+工厂模式的main函数
//int main()
//{
//    using namespace std;
//
//    cCashContext_Factory* pContext = NULL;
//
//    try {
//        int type = 0;
//        cout << "0 --> 普通收费" << endl << "1 --> 打8折" << endl << "2 --> 满300返100" << endl << "请选择收费方式:";
//        cin >> type;
//        pContext = new cCashContext_Factory(type);
//
//        cout << endl << "总费用为:";
//        double totalPrice = 0;
//        cin >> totalPrice;
//
//        cout << endl << "应收费为:" << pContext->AcceptCash(totalPrice) << endl;
//    }
//    catch (int type) {
//        cout << "没有" << type << "这种收费方式。" << endl;
//    }
//    catch (...) {
//        cout << "输入错误" << endl;
//    }
//
//    if (pContext)
//        delete pContext;
//
//    return 0;
//}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值