• <First Head设计模式>装饰器模式使用前的代码设计


    今天读到了<First Head设计模式>装饰器这一章,对文中一开始的例子比较感兴趣.文中介绍了一个咖啡售卖系统如何设计的问题.一开始是通过设计一个基类来计算所用的调料的价格,而用子类来计算特定品种的整体价格.

    这里面比较感兴趣的是文中有一个子类的实现: 在子类中直接通过父类名::方法来调用父类的方法,之前不怎么用继承,感到比较新奇,就自己码代码尝试了下.

    程序的UML图大致如下,真正重要的函数是cost()函数,用来得出咖啡的最终价格.

     1 //Beverage.h
     2 #pragma once
     3 #include <iostream>
     4 using namespace std;
     5 
     6 class Beverage
     7 {
     8 public:
     9     Beverage(bool bMilk, bool bSugar, double dCostMilk, double dCostSugar);
    10     virtual ~Beverage();    //基类析构用virtual,为了保证多态析构时能够找到子类的析构函数(不用virtual,基类指针是找不到子类的析构函数的位置的)
    11 
    12     virtual double cost();
    13     bool HasMilk();
    14     bool HasSugar();
    15 protected:
    16 private:
    17     bool m_bMilk;
    18     bool m_bSugar;
    19     double m_dCostMilk;
    20     double m_dCostSugar;
    21 };
     1 //Beverage.cpp
     2 #include "Beverage.h"
     3 
     4 Beverage::~Beverage()
     5 {
     6     cout << "Beverage is Over~" << endl;
     7 }
     8 
     9 Beverage::Beverage(bool bMilk, bool bSugar, double dCostMilk, double dCostSugar):
    10 m_bMilk(bMilk), m_bSugar(bSugar), m_dCostMilk(dCostMilk), m_dCostSugar(dCostSugar)
    11 {
    12     cout << "Beverage Begins~" << endl;
    13 }
    14 
    15 bool Beverage::HasMilk()
    16 {
    17     return m_bMilk;
    18 }
    19 
    20 bool Beverage::HasSugar()
    21 {
    22     return m_bSugar;
    23 }
    24 
    25 //计算配料最终花了多少钱
    26 double Beverage::cost()
    27 {
    28     double sum0 = 0;
    29     if(HasMilk())
    30     {
    31         sum0 += m_dCostMilk;
    32     }
    33 
    34     if (HasSugar())
    35     {
    36         sum0 += m_dCostSugar;
    37     }
    38     return sum0;
    39 }
    //DarkRoastCoffee.h
    #pragma once
    #include "Beverage.h"
    
    class DarkRoastCoffee : public Beverage
    {
    public:
        DarkRoastCoffee(double myCost,bool bMilk, bool bSugar, double dCostMilk, double dCostSugar);
    
        ~DarkRoastCoffee();
    
        double cost();
        char * Description();
        double GetMyCost();
    
    private:
        double m_dMyCost;
    };
     1 //DarkRoastCoffee.cpp
     2 #include "DarkRoastCoffee.h"
     3 
     4 //在子类的构造函数中,调用父类的有参构造函数.  注意初始化成员列表需要放在函数定义中,因为最后的")"后面要跟着"{"
     5 DarkRoastCoffee::DarkRoastCoffee(double myCost,bool bMilk, bool bSugar, double dCostMilk, double dCostSugar):Beverage(bMilk, bSugar, dCostMilk, dCostSugar), m_dMyCost(myCost)
     6 {
     7     cout << "DarkRoastCoffee Begins~" << endl;
     8 }
     9 
    10 double DarkRoastCoffee::GetMyCost()
    11 {
    12     return m_dMyCost;
    13 }
    14 
    15 DarkRoastCoffee::~DarkRoastCoffee()
    16 {
    17     cout << "DarkRoastCoffee is Over~" << endl;
    18 }
    19 
    20 double DarkRoastCoffee::cost()
    21 {
    22     return    Beverage::cost() + GetMyCost();    

    //注意此时用了父类::方法,这里的Beverage::cost()不必是static,因为在该方法执行时父类对象已经创建了(若是在无继承关系的别的类中,cost必须要是static了) //当然这里Beverage::cost()也不能是static,因为static函数不能为virtual. 24 }

    输出结果:

     1 //CoffeeCost.cpp
     2 
     3 #include "Beverage.h"
     4 #include "DarkRoastCoffee.h"
     5 
     6 int main()
     7 {
     8     DarkRoastCoffee dc(10, false, true, 2, 4);
     9     cout << dc.cost() << endl;
    10     return 0;
    11 }
    新战场:https://blog.csdn.net/Stephen___Qin
  • 相关阅读:
    maven上传jar包规范
    java.util.ConcurrentModificationException
    求集合中的最大值和最小值
    对象/集合转换成json
    字符串直接赋值和构造赋值的区别
    CSV文件读取
    读取properties配置文件
    图片轮播 js代码
    工作流数据库字段设计-审批流程。。
    @Html.Partials 加载分布视图传参数
  • 原文地址:https://www.cnblogs.com/Stephen-Qin/p/12180953.html
Copyright © 2020-2023  润新知