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

本文深入解析装饰者模式,探讨其如何在不修改原有类的基础上扩展功能,提供比继承更灵活的解决方案。通过C++实例,展示如何为咖啡类动态添加调料,实现功能增强。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

                                                                                                                                             --《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   //加了摩卡和牛奶的黑咖啡

 

内容概要:本文档详细介绍了基于MATLAB实现多目标差分进化(MODE)算法进行无人机三维路径规划的项目实例。项目旨在提升无人机在复杂三维环境中路径规划的精度、实时性、多目标协调处理能力、障碍物避让能力和路径平滑性。通过引入多目标差分进化算法,项目解决了传统路径规划算法在动态环境和多目标优化中的不足,实现了路径长度、飞行安全距离、能耗等多个目标的协调优化。文档涵盖了环境建模、路径编码、多目标优化策略、障碍物检测与避让、路径平滑处理等关键技术模块,并提供了部分MATLAB代码示例。 适合人群:具备一定编程基础,对无人机路径规划和多目标优化算法感兴趣的科研人员、工程师和研究生。 使用场景及目标:①适用于无人机在军事侦察、环境监测、灾害救援、物流运输、城市管理等领域的三维路径规划;②通过多目标差分进化算法,优化路径长度、飞行安全距离、能耗等多目标,提升无人机任务执行效率和安全性;③解决动态环境变化、实时路径调整和复杂障碍物避让等问题。 其他说明:项目采用模块化设计,便于集成不同的优化目标和动态环境因素,支持后续算法升级与功能扩展。通过系统实现和仿真实验验证,项目不仅提升了理论研究的实用价值,还为无人机智能自主飞行提供了技术基础。文档提供了详细的代码示例,有助于读者深入理解和实践该项目。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值