C++设计模式--装饰者模式

装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

                                                                                                                                             --《Head First 设计模式》

装饰者模式简单来说就是对已有的类进行拓展但有不要求修改已有的类的代码,也就是符合了“对扩展开放,对修改关闭”的设计原则。

装饰者模式的优缺点:

优点

           1、装饰者模式可以提供比继承更多的灵活性

           2、可以通过一种动态的方式来扩展一个对象的功能,在运行时选择不同的装饰器,从而实现不同的行为。

           3、通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。可以使用多个具体装饰类来装饰同一对象,得到功能更为强大的对象。

           4、具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”。

缺点

           1、会产生很多的小对象,增加了系统的复杂性

           2、这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。

 

装饰者模式的使用场景

  1、在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。

  2、需要动态地给一个对象增加功能,这些功能也可以动态地被撤销。  当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。

(以上内容来源于网络)

 

C++实现装饰者模式:

场景:原有饮料类,咖啡类继承了饮料了。现在需要添加调料类,为咖啡添加调料,要求不能修改原有的类。

#ifndef __BEVERAGE_H__
#define __BEVERAGE_H__

#include <string>
/*
 * 饮料类
*/
class Beverage
{
public:
    virtual std::string getDescription() const
    {
        return description;
    }

    virtual double cost() = 0;

public:
    std::string description = "Unknow Beverage";
};
#endif

 

#ifndef __COFFEE_H__
#define __COFFEE_H__

//咖啡类
#include "beverage.h"

//浓咖啡
class Espresso : public Beverage
{

public:
    Espresso();
    ~Espresso();
    virtual std::string getDescription() const override;
    virtual double cost() override;
};


//黑咖啡
class HouseBlend : public Beverage
{
public:
    HouseBlend();
    ~HouseBlend();
    virtual std::string getDescription() const override;
    virtual double cost() override;
};
#endif

 

//咖啡实现类
#include "coffee.h"

Espresso::Espresso()
{
    description = "Espresso";
}

Espresso::~Espresso()
{
}

std::string Espresso::getDescription() const
{
    return description;
}

double Espresso::cost()
{
    return 1.99;
}

HouseBlend::HouseBlend()
{
    description = "HouseBlend";
}

HouseBlend::~HouseBlend()
{
}

std::string HouseBlend::getDescription() const
{
    return description;
}

double HouseBlend::cost()
{
    return .89;
}

 

以下是调味料的实现:

#ifndef __CONDIMENTDECORATOR_H__
#define __CONDIMENTDECORATOR_H__

#include <string>

#include "beverage.h"

//调料装饰类
class CondimentDecorator : public Beverage
{
public:
    virtual std::string getDescription() const override = 0;
    virtual double cost() override = 0;
};

//调料--摩卡
class Mocha : public CondimentDecorator
{
public:
    explicit Mocha(Beverage* beverage);
    ~Mocha();
    virtual std::string getDescription() const override;
    virtual double cost() override;

private:
    Beverage* m_beverage;
};

//调料--牛奶
class Milk : public CondimentDecorator
{
public:
    explicit Milk(Beverage* beverage);
    ~Milk();
    virtual std::string getDescription() const override;
    virtual double cost() override;

private:
    Beverage* m_beverage;

};

#endif
#include "condimentdecorator.h"

Mocha::Mocha(Beverage* beverage):m_beverage(beverage)
{

}

Mocha::~Mocha()
{

}

std::string Mocha::getDescription() const
{
    return m_beverage->getDescription() + ",Mocha";
}

double Mocha::cost()
{
    return m_beverage->cost() + .20;
}

Milk::Milk(Beverage* beverage):m_beverage(beverage)
{

}

Milk::~Milk()
{

}

std::string Milk::getDescription() const
{
    return m_beverage->getDescription() + ",Milk";
}

double Milk::cost()
{
    return m_beverage->cost() + .50;
}

 

生产咖啡并添加调料:

#include <iostream>

#include "beverage.h"
#include "coffee.h"
#include "condimentdecorator.h"

using namespace std;
int main()
{
    Beverage* beverage = new Espresso(); 
    Beverage* beverage2 = new HouseBlend();
    cout << beverage->getDescription() << " and cost = " 
         << beverage->cost() << endl;

    cout << beverage2->getDescription() << " and cost = "
             << beverage2->cost() << endl;
    
    //为HouseBlend的咖啡加上摩卡
    beverage2 = new Mocha(beverage2);
    cout << beverage2->getDescription() << " and cost = "
             << beverage2->cost() << endl;
    
    //再为加了摩卡的HouseBlend咖啡加上牛奶
    beverage2 = new Milk(beverage2);
    cout << beverage2->getDescription() << " and cost = "
             << beverage2->cost() << endl;

    delete beverage;
    delete beverage2;
    return 0;
}

 

Linux下编译:

g++ -std=c++11 -o main main.cc coffee.cc condimentdecorator.cc
./main

结果是:

Espresso and cost = 1.99                //没有加调料的浓咖啡
HouseBlend and cost = 0.89              //没有加调料的黑咖啡
HouseBlend,Mocha and cost = 1.09        //加了摩卡的黑咖啡
HouseBlend,Mocha,Milk and cost = 1.59   //加了摩卡和牛奶的黑咖啡

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
设计模式是在软件开发中常用的一种编程思想,它提供了一种解决问题的方法论,可以帮助开发者更加灵活和高效地开发软件。基于qt4开源跨平台开发框架的PDF设计模式主要包括以下几个方面。 首先,观察者模式是一种常用的设计模式,它可以用于实现PDF文件的订阅和通知功能。通过该模式,用户可以选择关注自己感兴趣的PDF文件,并在文件更新时接收到通知。 其次,工厂模式是常用的创建型设计模式,它可以帮助开发者根据需要创建不同类型的PDF文件。例如,可以使用工厂模式创建基本的PDF文件、加密的PDF文件或者带有水印的PDF文件。 再次,装饰器模式是一种结构型设计模式,可以用于在不修改现有代码的情况下为PDF文件添加额外的功能。开发者可以通过装饰器模式为PDF文件添加页眉、页脚、书签等功能,同时保持原有的PDF文件结构和功能不受影响。 此外,策略模式也是常用的设计模式之一,在PDF开发中可以用于实现不同的压缩策略和加密策略。通过策略模式,开发者可以根据需求选择不同的策略来实现对PDF文件的处理和管理。 最后,单例模式是一种创建型设计模式,可以确保在整个应用程序中只有一个PDF文件实例。通过单例模式,可以在不同的模块中共享同一个PDF文件对象,避免资源浪费和数据冲突。 总而言之,设计模式在基于qt4开源跨平台开发框架的PDF开发中具有重要的作用。以上提到的几种设计模式可以帮助开发者更好地组织和管理PDF文件,提高开发效率和代码的可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值