C++常用设计模式之:装饰器模式

装饰器模式是非常特殊的一个模式,它既用到了继承也用到了组合,而继承和组合也是设计模式中常用的手法。

装饰器模式的定义:是在不比改变原来类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

用现实中的列子来类比,例如:我们喝奶茶或者果汁的时候,可以添加不同的辅料,椰果、珍珠、冰块、糖等等。通过这些原料我们可以自己组合成自己喜爱的饮料。

UML结构图如下:

                                     

下面我用伪码来表述上面的例子。

//饮料类
class Drinks
{
  public:
       virtual int Price() = 0;//饮料的价格
};


//奶茶类
class MilkyTea : public Drinks
{
  public:
       int Price(){
       return 10; //单独的奶茶卖10块钱一杯
       }
};

//果汁类
class FruitJuice: public Drinks
{
  public:
       int Price(){
       return 8; //单独的果汁卖8块钱一杯
       }
};

//奶茶类和果汁类都继承自饮料类--这里就是装饰器模式中所说的“原来类文件和使用继承的情况”。
//我们需要的是“动态地扩展一个对象的功能”,这里就是扩展奶茶类和果汁类的功能
//辅料类,就是装饰类Decorator,这里我们理解添加的辅料就是这些饮料的装饰
//这个装饰类是整个装饰器模式的精华,既有继承也有组合
class Decorator: public Drinks//既有继承
{
protected:
      Drinks *m_pDrinks;//也有组合

public:
      Decorator(Drinks *pDrinks) : m_pDrinks(pDrinks) {}

       virtual int Price(){
       //这里就可以加一些我们自己的操作了
       return pDrinks->Price();
       }
   
};

//具体的辅料(装饰)
//椰果
class Coconut : public Decorator
{
public:
     Coconut(Drinks *pDrinks) : Decorator(pDrinks) {}
    
     int Price(){
     return m_pDrinks->Price() + 2;//加椰果的饮料就要在原来的基础上加2块钱
     }
}

//珍珠
class Pearl: public Decorator
{
public:
     Pearl(Drinks *pDrinks) : Decorator(pDrinks) {}
    
     int Price(){
     return m_pDrinks->Price() + 3;//加珍珠的饮料就要在原来的基础上加3块钱
     }
}

//应用
int main()
{
   //来一杯奶茶
   Drinks *pDrinks = new MilkyTea();
   std::cout<<"Price ="<<pDrinks->Price()<<std::endl;

   //来一杯奶茶+椰果
   Decorator *pDecoratorCoconut = new Coconut(pDrinks);
   std::cout<<"Price ="<<pDecoratorCoconut->Price()<<std::endl;
   
   //来一杯奶茶+珍珠
   Decorator *pDecoratorPearl = new Pearl(pDrinks);
   std::cout<<"Price ="<<pDecoratorPearl->Price()<<std::endl;

   //果汁同理这里就不写了
}

现在返回那张UML图我们再来看:

                                 

结合到我们的例子和装饰器模式的定义,其中稳定的部分就是我们的饮料类以及奶茶类和果汁类,这个是我们不能动的。另外我们增加的装饰器类也是稳定的,因为在这个类中我们并没有具体的指向某一种饮料,而是指向了它们的父类。变化的部分是从饮料类可能再继承出来的新的类,以及我们后面增加的具体的装饰(这里就是各种辅料:椰果、珍珠等)。 我们是通过继承和组合的方式来动态扩展饮料类对象的功能。

最后,如果理解的有偏差,还请指出!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值