设计模式学习笔记(三):装饰者模式

本文介绍装饰者模式的概念、UML图、实例分析及其适用场景。通过装修房子的例子,详细展示了如何利用装饰者模式动态地给对象添加职责。

一.概念

     动态的给一个对象添加额外的职责。想要扩展功能的话,装饰者提供了一种有别于继承的另外一种选择。

 

二.UML

  1. Component(概念中提到的对象接口),也就是“被装饰者”。
  2. ConcreateComponent(未添加任何职责的,对象接口的子类)。
  3. Decorator(装饰者抽象类),扩张了对象接口的功能。
  4. ConcreteDrcorator(具体装饰类),具体怎么装饰对象接口的在这些类里面反映。

三.实例分析

    家里买了一套房子,需要装修,考虑到预算只有这么多,不能采用全包的方式,于是采用将装修工作细化,以节省开销。

     House

Java代码   收藏代码
  1. package com.zzy.decorator;  
  2.   
  3. /** 
  4.  * 被装修者-房子 
  5.  * @author eason 
  6.  * 
  7.  */  
  8. public interface House {  
  9.     public void decorate();  
  10. }  

 

     BlankHouse

Java代码   收藏代码
  1. package com.zzy.decorator;  
  2.   
  3. /** 
  4.  * 未经装修的房子 
  5.  * @author eason 
  6.  * 
  7.  */  
  8. public class BlankHouse implements House{  
  9.   
  10.     @Override  
  11.     public void decorate() {  
  12.         System.out.println("未经装修的房子");  
  13.     }  
  14.   
  15. }  

 

     Decorator

Java代码   收藏代码
  1. package com.zzy.decorator;  
  2.   
  3. /** 
  4.  * 装修工抽象类 
  5.  * @author eason 
  6.  * 
  7.  */  
  8. public class Decorator implements House{  
  9.       
  10.     private House house;  
  11.       
  12.     public Decorator(House house) {  
  13.         this.house = house;  
  14.     }  
  15.   
  16.     @Override  
  17.     public void decorate() {  
  18.         house.decorate();  
  19.     }  
  20.   
  21. }  

 

     ElectricWirer

Java代码   收藏代码
  1. package com.zzy.decorator;  
  2.   
  3. /** 
  4.  * 电线工 
  5.  * @author eason 
  6.  * 
  7.  */  
  8. public class ElectricWirer extends Decorator {  
  9.       
  10.     public ElectricWirer(House house) {  
  11.         super(house);  
  12.     }  
  13.   
  14.     @Override  
  15.     public void decorate() {  
  16.         super.decorate();  
  17.         //自己的逻辑-具体怎么包装的写在super.decorate()的前后任何地方  
  18.         System.out.println("已经装修完电线");  
  19.     }  
  20. }  
 

 

     Floorer

Java代码   收藏代码
  1. package com.zzy.decorator;  
  2.   
  3. /** 
  4.  * 地板工 
  5.  * @author eason 
  6.  * 
  7.  */  
  8. public class Floorer extends Decorator {  
  9.       
  10.     public Floorer(House house) {  
  11.         super(house);  
  12.     }  
  13.   
  14.     @Override  
  15.     public void decorate() {  
  16.         super.decorate();  
  17.         //自己的逻辑-具体怎么包装的写在super.decorate()的前后任何地方  
  18.         System.out.println("已经装修完地板");  
  19.     }  
  20. }  
 

 

     WaterPiper

Java代码   收藏代码
  1. package com.zzy.decorator;  
  2.   
  3. /** 
  4.  * 水管工 
  5.  * @author eason 
  6.  * 
  7.  */  
  8. public class WaterPiper extends Decorator {  
  9.       
  10.     public WaterPiper(House house) {  
  11.         super(house);  
  12.     }  
  13.   
  14.     @Override  
  15.     public void decorate() {  
  16.         super.decorate();  
  17.         //自己的逻辑-具体怎么包装的写在super.decorate()的前后任何地方  
  18.         System.out.println("已经装修完水管");  
  19.     }  
  20. }  
 

 

     TestDecorator

Java代码   收藏代码
  1. package com.zzy.decorator;  
  2.   
  3. /** 
  4.  * 测试类 
  5.  * @author eason 
  6.  * 
  7.  */  
  8. public class TestDecorator {  
  9.   
  10.     public static void main(String[] args) {  
  11.         //空白房子一个  
  12.         House house = new BlankHouse();  
  13.         //一层层装修  
  14.         Decorator dec = new Floorer(new ElectricWirer(new WaterPiper(house)));  
  15.         dec.decorate();  
  16.     }  
  17.   
  18. }  

 

四.使用场景

  1. 为已有组件动态添加更多功能。

五.使用感受

  1. 将装饰功能的代码从Component里面提了出来,简化了Component。
  2. 客户端可以在运行时根据需要,选择需要的功能来包装Component。
  3. 继承是扩展功能的方式之一,但并不见得是达到弹性设计的最佳形方式。
  4. 组合和委托可用于在运行时动态地加上新的行为。装饰者模式实际上就是组合和委托。再次提到组合和委托,第一次提到是在策略模式 里面。
  5. 在日常的设计中,应该允许行为被扩展,而不需修改现有的代码。
  6. 装修者会导致设计中出现许多小对象,如果过度使用,会让程序变的复杂。
### 光流法C++源代码解析与应用 #### 光流法原理 光流法是一种在计算机视觉领域中用于追踪视频序列中运动物体的方法。它基于亮度不变性假设,即场景中的点在时间上保持相同的灰度值,从而通过分析连续帧之间的像素变化来估计运动方向和速度。在数学上,光流场可以表示为像素位置和时间的一阶导数,即Ex、Ey(空间梯度)和Et(时间梯度),它们共同构成光流方程的基础。 #### C++实现细节 在给定的C++源代码片段中,`calculate`函数负责计算光流场。该函数接收一个图像缓冲区`buf`作为输入,并初始化了几个关键变量:`Ex`、`Ey`和`Et`分别代表沿x轴、y轴和时间轴的像素强度变化;`gray1`和`gray2`用于存储当前帧和前一帧的平均灰度值;`u`则表示计算出的光流矢量大小。 #### 图像处理流程 1. **初始化和预处理**:`memset`函数被用来清零`opticalflow`数组,它将保存计算出的光流数据。同时,`output`数组被填充为白色,这通常用于可视化结果。 2. **灰度计算**:对每一像素点进行处理,计算其灰度值。这里采用的是RGB通道平均值的计算方法,将每个像素的R、G、B值相加后除以3,得到一个近似灰度值。此步骤确保了计算过程的鲁棒性和效率。 3. **光流向量计算**:通过比较当前帧和前一帧的灰度值,计算出每个像素点的Ex、Ey和Et值。这里值得注意的是,光流向量的大小`u`是通过`Et`除以`sqrt(Ex^2 + Ey^2)`得到的,再乘以10进行量化处理,以减少计算复杂度。 4. **结果存储与阈值处理**:计算出的光流值被存储在`opticalflow`数组中。如果`u`的绝对值超过10,则认为该点存在显著运动,因此在`output`数组中将对应位置标记为黑色,形成运动区域的可视化效果。 5. **状态更新**:通过`memcpy`函数将当前帧复制到`prevframe`中,为下一次迭代做准备。 #### 扩展应用:Lukas-Kanade算法 除了上述基础的光流计算外,代码还提到了Lukas-Kanade算法的应用。这是一种更高级的光流计算方法,能够提供更精确的运动估计。在`ImgOpticalFlow`函数中,通过调用`cvCalcOpticalFlowLK`函数实现了这一算法,该函数接受前一帧和当前帧的灰度图,以及窗口大小等参数,返回像素级别的光流场信息。 在实际应用中,光流法常用于目标跟踪、运动检测、视频压缩等领域。通过深入理解和优化光流算法,可以进一步提升视频分析的准确性和实时性能。 光流法及其C++实现是计算机视觉领域的一个重要组成部分,通过对连续帧间像素变化的精细分析,能够有效捕捉和理解动态场景中的运动信息
微信小程序作为腾讯推出的一种轻型应用形式,因其便捷性与高效性,已广泛应用于日常生活中。以下为该平台的主要特性及配套资源说明: 特性方面: 操作便捷,即开即用:用户通过微信内搜索或扫描二维码即可直接使用,无需额外下载安装,减少了对手机存储空间的占用,也简化了使用流程。 多端兼容,统一开发:该平台支持在多种操作系统与设备上运行,开发者无需针对不同平台进行重复适配,可在一个统一的环境中完成开发工作。 功能丰富,接口完善:平台提供了多样化的API接口,便于开发者实现如支付功能、用户身份验证及消息通知等多样化需求。 社交整合,传播高效:小程序深度嵌入微信生态,能有效利用社交关系链,促进用户之间的互动与传播。 开发成本低,周期短:相比传统应用程序,小程序的开发投入更少,开发周期更短,有助于企业快速实现产品上线。 资源内容: “微信小程序-项目源码-原生开发框架-含效果截图示例”这一资料包,提供了完整的项目源码,并基于原生开发方式构建,确保了代码的稳定性与可维护性。内容涵盖项目结构、页面设计、功能模块等关键部分,配有详细说明与注释,便于使用者迅速理解并掌握开发方法。此外,还附有多个实际运行效果的截图,帮助用户直观了解功能实现情况,评估其在实际应用中的表现与价值。该资源适用于前端开发人员、技术爱好者及希望拓展业务的机构,具有较高的参考与使用价值。欢迎查阅,助力小程序开发实践。资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值