c++设计模式之装饰器模式

作用

为现有类增加功能

案例说明

cpp 复制代码
class Car
{
public:
    virtual void show()=0;    
};

class Bmw:public Car
{
public:
    void show(){cout<<"宝马汽车>>"<<endl;}
};

class Audi:public Car
{
public:
    void show(){cout<<"奥迪汽车>>"<<endl;}
};

class Bcw:public Car{
public:
    void show(){cout<<"奔驰汽车>>"<<endl;}
};

如上,我们定义了汽车抽象类,并定义三个具体的汽车类。

现在的问题是:如果需要给这三种汽车都增加仨个功能------定速导航、刹车、车道偏离。应该如何实现?

  • 第一种办法,为每个汽车类都定义两个功能子类,如下图所示
  • 第二种办法,使用装饰器,只需要给Car下增加一个功能类
cpp 复制代码
class CarFunction:public Car{
public:
    CarFunction(Car* carPtr):_carPtr(carPtr){};
protected :
    Car* _carPtr;
};
//装饰器1,定速导航
class ConcreteDecorator:public CarFunction
{
public:
    ConcreteDecorator(Car* carPtr):CarFunction(carPtr){};
    void show()
    {
        _carPtr->show();
        cout<<"\t定速巡航"<<endl;
    }
};

//装饰器2,刹车
class BrakeDecorator:public CarFunction
{
public:
    BrakeDecorator(Car* carPtr):CarFunction(carPtr){}
    void show()
    {
        _carPtr->show();
        cout<<"\t刹车"<<endl;
    }
};

//车道偏离
class LaneDecorator:public CarFunction
{
public:
    LaneDecorator(Car* carPtr):CarFunction(carPtr){}
    void show(){
        _carPtr->show();
        cout<<"\t车道偏离"<<endl;
    }
};

代码测试

cpp 复制代码
void test()
{
    Car* p1=new ConcreteDecorator(new Bmw());//使用宝马汽车定位导航功能
    Car* p2=new BrakeDecorator(new Audi());//使用奥迪汽车请假刹车功能
    Car* p3=new LaneDecorator(new Bcw());//使用奔驰汽车车道偏离功能
    p1->show();
    p2->show();
    p3->show();
}

可以看到,使用装饰器模式给类增加功能的优点就是避免了大量的代码重复,假如使用继承子类的方式给各种汽车类增加功能,这种重复的功能增加会产生大量冗余的代码

对比代理模式(详见c++设计模式之代理模式-CSDN博客),装饰器模式和代理模式的设计都有许多相似之处

他们都通过将真实的对象包装到代理类和装饰类中,或者说把实际的操作对象放到代理类或装饰类中来达成目的 。他们利用的特性都是基于c++的多态特性

但他们的目的不同

  • 代理模式 主要是为了控制对真实对象的访问
  • 装饰器模式 主要是为了给真实对象增加功能
相关推荐
No0d1es3 小时前
电子学会青少年软件编程(C/C++)5级等级考试真题试卷(2024年6月)
c语言·c++·算法·青少年编程·电子学会·五级
DjangoJason4 小时前
C++ 仿RabbitMQ实现消息队列项目
开发语言·c++·rabbitmq
weixin_307779136 小时前
VS Code配置MinGW64编译GNU 科学库 (GSL)
开发语言·c++·vscode·算法
Zyy~8 小时前
《设计模式》工厂方法模式
设计模式·工厂方法模式
蒋星熠8 小时前
C++零拷贝网络编程实战:从理论到生产环境的性能优化之路
网络·c++·人工智能·深度学习·性能优化·系统架构
CHANG_THE_WORLD9 小时前
# C++ 中的 `string_view` 和 `span`:现代安全视图指南
开发语言·c++
雨落倾城夏未凉9 小时前
9.c++new申请二维数组
c++·后端
雨落倾城夏未凉9 小时前
8.被free回收的内存是立即返还给操作系统吗?为什么?
c++·后端
雨落倾城夏未凉9 小时前
6.new和malloc的区别
c++·后端
郝学胜-神的一滴9 小时前
深入理解QFlags:Qt中的位标志管理工具
开发语言·c++·qt·程序人生