当前位置: 首页 > news >正文

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

作用

为现有类增加功能

案例说明


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下增加一个功能类

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;}
};

代码测试

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++的多态特性

但他们的目的不同

  • 代理模式主要是为了控制对真实对象的访问
  • 装饰器模式主要是为了给真实对象增加功能

相关文章:

  • 为电子表格嵌入数据库,Excel/WPS一键升级为管理系统
  • 零基础学Python之网络编程
  • 【Linux】缓冲区与缓冲区的刷新策略
  • 微信自动预约小程序开发指南:从小白到专家
  • 中兴R5300G4服务器查看服务器、主板序列号及硬盘RAID信息
  • 小白都能看懂的力扣算法详解——链表(一)
  • Linux文件和目录管理
  • 上海亚商投顾:成交量突破万亿 沪指重回2800
  • C++中的class
  • Golang 基础 环境配置和包管理
  • PyTorch深度学习实战(23)——从零开始实现SSD目标检测
  • Nacos安装,服务注册,负载均衡配置,权重配置以及环境隔离
  • 【Python基础】案例分析:电影分析
  • 飞天使-k8s知识点16-kubernetes实操1-pod
  • Leetcode 213 打家劫舍 II
  • 9月CHINA-PUB-OPENDAY技术沙龙——IPHONE
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • ➹使用webpack配置多页面应用(MPA)
  • Android 初级面试者拾遗(前台界面篇)之 Activity 和 Fragment
  • Android单元测试 - 几个重要问题
  • HTTP--网络协议分层,http历史(二)
  • js中的正则表达式入门
  • Just for fun——迅速写完快速排序
  • LeetCode541. Reverse String II -- 按步长反转字符串
  • Nacos系列:Nacos的Java SDK使用
  • React16时代,该用什么姿势写 React ?
  • Redis 中的布隆过滤器
  • Spring Cloud(3) - 服务治理: Spring Cloud Eureka
  • Webpack入门之遇到的那些坑,系列示例Demo
  • 高性能JavaScript阅读简记(三)
  • 官方解决所有 npm 全局安装权限问题
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 码农张的Bug人生 - 见面之礼
  • 使用 5W1H 写出高可读的 Git Commit Message
  • 通过npm或yarn自动生成vue组件
  • 系统认识JavaScript正则表达式
  • 移动端 h5开发相关内容总结(三)
  • #Z2294. 打印树的直径
  • #经典论文 异质山坡的物理模型 2 有效导水率
  • $(selector).each()和$.each()的区别
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • (175)FPGA门控时钟技术
  • (二十一)devops持续集成开发——使用jenkins的Docker Pipeline插件完成docker项目的pipeline流水线发布
  • (附程序)AD采集中的10种经典软件滤波程序优缺点分析
  • (附源码)计算机毕业设计ssm电影分享网站
  • (算法)Game
  • .gitignore文件设置了忽略但不生效
  • .NET 设计一套高性能的弱事件机制
  • .net通用权限框架B/S (三)--MODEL层(2)
  • ;号自动换行
  • @EnableAsync和@Async开始异步任务支持
  • @SuppressWarnings注解
  • @Valid和@NotNull字段校验使用
  • @拔赤:Web前端开发十日谈