zoukankan      html  css  js  c++  java
  • 第30章 混编模式(2)

    30.2 迷你版交易系统(工厂模式+策略模式)

    30.2.1 IC卡的两种金额

    (1)固定金额:指员工不能提现的金额,这部分金额只能用来特定消费,即员工日常必需的消费,如食堂内吃饭、理发、健身等活动。

    (2)自由金额:可以提现,也可以用于消费,

    30.2.2 扣款策略(假设卡内有充足的余额)

    (1)策略1:会对IC卡的两个金额产生影响

          IC卡固定余额 = IC卡现有固定金额 - 交易金额 / 2

          IC卡自由余额 = IC卡现有自由金额 - 交易金额 / 2

    (2)策略2:全部从自由金额上操除

    30.2.3 类图

     

    【编程实验】迷你版交易系统

    //设计模式混编——工厂模式+策略模式
    //实例:迷你版的交易系统
    /*
    说明:
    1. 每个员工都有一张IC卡,包含固定金额和自由金额
    2. 固定金额指员工不能提现的金额,这部分金额只能用来特定消费,即
       员工日常必需的消费,如食堂内吃饭、理发、健身等活动
    3. 自由金额:可以提现,也可以用于消费,
    扣款策略(本例假设IC卡里有充足的余额)
    策略1:会对IC卡的两个金额产生影响
          IC卡固定余额 = IC卡现有固定金额 - 交易金额 / 2
          IC卡自由余额 = IC卡现有自由金额 - 交易金额 / 2
    策略2:全部从自由金额上操除。
    */
    #include <iostream>
    #include <string>
    #include <list>
    
    using namespace std;
    
    //*******************************************辅助类***********************************
    //交易信息
    class Trade
    {
    private:
        string tradeNo; //交易编号
        int amount;     //交易金额
    public:
        Trade():tradeNo(""),amount(0){}
        string getTradeNo(){return tradeNo;}
        void setTradeNo(string value)
        {
            tradeNo = value;
        }
    
        int getAmount(){return amount;}
        void setAmount(int value)
        {
            amount = value;
        }
    };
    
    //IC卡信息
    class Card
    {
    private:
        string cardNo; //IC卡号码
        int steadyMoney; //固定交易金额
        int freeMoney;   //自由交易金额
    public:
        string getCarNo(){return cardNo;}
        void setCardNo(string value)
        {
            cardNo = value;
        }
    
        int getSteadyMoney(){return steadyMoney;}
        void setSteadyMoney(int value)
        {
            steadyMoney = value;
        }
    
        int getFreeMoney(){return freeMoney;}
        void setFreeMoney(int value)
        {
            freeMoney = value;
        }
    };
    
    //**********************************策略接口*****************************
    //扣款策略接口
    class IDeduction
    {
        //扣款,提供交易和卡信息,进行扣款,并返回扣款是否成功
    public:
        virtual bool exec(Card& card, Trade& trade) = 0;
        virtual ~IDeduction(){}
    };
    
    //扣款策略1
    class SteadyDeduction : public IDeduction
    {
    public:
        //固定交易扣款
        bool exec(Card& card, Trade& trade)
        {
            //分别从固定金额和自由金额中扣除
            int halfMoney = trade.getAmount() / 2;
            card.setFreeMoney(card.getFreeMoney() - halfMoney);
            card.setSteadyMoney(card.getSteadyMoney() - halfMoney);
            return true;
        }
    };
    
    //扣款策略2
    class FreeDeduction :public IDeduction
    {
    public:
        //自由扣款
        bool exec(Card& card, Trade& trade)
        {
            //直接从自由余额中扣除
            card.setFreeMoney(card.getFreeMoney() - trade.getAmount());
            return true;
        }
    };
    
    //扣款策略的上下文环境
    class DeductionContext
    {
    private:
        //持有扣款策略的引用
        IDeduction* deduction;
    public:
        //构造函数传入策略
        DeductionContext(IDeduction* deduction)
        {
            this->deduction = deduction;
        }
        //执行扣款
        bool exec(Card& card, Trade& trade)
        {
            return deduction->exec(card, trade);
        }
    };
    
    //***********************************工厂类*****************************
    class StrateFactory
    {
    public:
        static IDeduction* getDeduction(string type)
        {
            IDeduction* ret = NULL;
            if (type == "free")
            {
                 ret = new FreeDeduction();
            }else if(type == "steady")
            {
                 ret = new SteadyDeduction();
            }
            return ret;
        }
    };
    
    //初始化IC卡
    void initIC(Card& card)
    {
        //IC卡
        card.setCardNo("1100010001000");
        card.setFreeMoney(1000);//1000元
        card.setSteadyMoney(800); //800元
    }
    
    //打印出当前卡内交易金额
    void showCard(Card& card)
    {
        cout <<"IC卡编号:" << card.getCarNo() << endl;
        cout << "固定类型金额:" << card.getSteadyMoney() << endl;
        cout << "自由类型金额:" << card.getFreeMoney() << endl;
    }
    
    int main()
    {
    
        Card card;
        initIC(card); //初始化一张IC卡
    
        cout <<"========初始化信息:========" << endl;
        showCard(card); //显示卡内信息
    
        //一条交易记录
        Trade trade;
        trade.setTradeNo("abcdef");
        trade.setAmount(100);
    
        //交易策略
        IDeduction* deduction = StrateFactory::getDeduction("steady"); //free或steady
        DeductionContext ctx(deduction);
        ctx.exec(card, trade);
    
        //交易成功,打印成功处理消息
        cout << "========交易凭证========" <<endl;
        cout << trade.getTradeNo() << "交易成功!"<<endl;
        cout << "本次发生的交易金额为:" << trade.getAmount() << "" << endl;
    
        //展示一下卡内信息
        showCard(card);
    
        delete deduction;
    
        return 0;
    };
    /*输出结果:
    ========初始化信息:========
    IC卡编号:1100010001000
    固定类型金额:800
    自由类型金额:1000
    ========交易凭证========
    abcdef交易成功!
    本次发生的交易金额为:100元
    IC卡编号:1100010001000
    固定类型金额:750
    自由类型金额:950
    */

    30.2.4 小结

    (1)策略模式:负责对扣款策略进行封装,保证两个策略可以自由切换,而且日后增加扣款策略也很容易。

    (2)工厂方法模式:修正策略模式必须对外暴露具体策略问题,由工厂方法模式直接产生一个具体的策略对象,而其他模块则不需要依赖具体的策略

  • 相关阅读:
    Android studio测试软件——Monkey学习及运用
    MockPlus原型设计介绍
    MockPlus,一款好用的原型设计软件
    44道JavaScript难题 ---- 送命题
    使用JSONP实现跨域
    XML-RPC简单理解与博客园的MetaWeblog协议
    新型冠状病毒防控知识问答
    树莓派搭建个人服务器
    树莓派也跑Docker和.NET Core
    BugNet使用指南
  • 原文地址:https://www.cnblogs.com/5iedu/p/5683622.html
Copyright © 2011-2022 走看看