C#面向对象设计模式纵横谈 学习笔记10 Decorator 装饰(结构型模式)

LVGL8.x 实体按键与Keypad驱动的无缝对接实战 本文详细解析了LVGL8.x中实体按键与Keypad驱动的两种对接方案:坐标映射的Button方式与事件驱动的Keypad方式。重点阐述了如何模块化裁剪lv_port_indev.c模板文件,并深入讲解了Keypad驱动与Group焦点管理系统的核心协作机制,为无触摸屏的嵌入式设备提供流畅的UI交互解决方案。 阅读详情

当我们在设计一个一个类继承结构的时候,我们可能会存在以下的情况。首先有一种坦克的抽象类,那么这个坦克会有很多中类型,那么我们就派生这个坦克吧。比如说有德国虎式坦克,轻型坦克和工程坦克,那么现在又有三种功能要扩展到这三种坦克上,如两栖功能、夜视功能、雷达功能,可以把这三种功能设置为接口。按类继承的设计方案,如果需要这三种坦克每种坦克都有相应的功能坦克,我们需要继承Tank类,并实现相应功能的接口,那么我们的扩展类就有9种,这还不包括功能的组合,那么现在问题就出来了,这种类继承的模式会导致子类无限制的增加,这是我们无法忍受的。那么怎么解决这个问题呢?我们就需要Decorator模式来解决。

Decorator模式的动机:

上述描述的问题根源在于我们“过度地使用了继承来扩展对象的功能”,由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀(多继承)。如何使“对象功能的扩展”能够根据需要来动态地实现?同时避免“扩展功能的增多”带来的子类膨胀问题?从而使得任何“功能扩展变化”所导致的影响将为最低?

Decorator模式的意图:

动态地给一个对象增加一些额外的职责。就增加功能而言,Decorator模式比生成子类更为灵活。

如何用代码来实现Decorator模式:

首先我们有一个抽象基类Tank,里面有两个抽象方法Shot和Run

public abstract class Tank
{
    
public abstract void Shot();
    
public abstract void Run();
}

我们有三个派生类来表明三种坦克的类型,并实现了Shot和Run方法

public class TigerTank : Tank
{
    
public override void Shot()
    
{
    }


    
public override void Run()
    
{
    }

}


public class LightTank : Tank
{
    
public override void Shot()
    
{
    }


    
public override void Run()
    
{
    }

}


public class ConsturctTank : Tank
{
    
public override void Shot()
    
{
    }


    
public override void Run()
    
{
    }

}
现在,我们按照往常的设计方法应该写功能接口interface了,但是功能接口会带来类的膨胀,这不是我们要的目的,那么我们看下面的代码式如何做的。
public abstract class Decorator : Tank //这里是一个接口继承
{
    
private Tank _tank;//Has a对象组合

    
public Decorator(Tank tank)
    
{
        _tank 
= tank;
    }

    
    
public override void Shot()
    
{
        _tank.Shot();
    }


    
public override void Run()
    
{
        _tank.Run();
    }

}

这是装饰接口的基类,他继承与Tank类,这里继承的Tank类不是一个is a的关系,他就像一个接口,规定了Decorator类要实现的方法。_tank作为一个Tank的实例,是一个Has a的对象组合关系。Decroator实现的Shot和Run方法是调用私有成员变量_tank的Shot和Run方法。

下面就是两栖功能的实现

public class Amphibian : Decorator
{
    
public Amphibian(Tank tank)
        : 
base(tank)
    
{
    }


    
public override void Shot()
    
{
        
//do some Externsion
        base.Shot();
    }


    
public override void Run()
    
{
        
//do some extension
        base.Run();
    }

}

Amphibian类继承了Decorator类,在Amphibian类中的Shot和Run方法中,我们首先根据我们的功能,做一些shot和Run之前做一些相应的扩展,然后调用基类的Shot和Run方法,这样做我们即做了相应的扩展,又调用基本的Shot和Run方法。

我们还可以根据其他功能扩展做相关扩展的类,并继承Decorator类

如何来使用相关的功能呢?

static void Main(string[] args)
{
    Tank tank 
= new TigerTank();

    Amphibian am 
= new Amphibian(tank);
    am.Shot();
}

在上面的代码中使用使用Amphibian来装饰tank,那么调用am.shot方法时,即扩展了两栖功能又使用了tank的原本的shot功能。如果现在还有一个红外功能要扩展,只需要实例化一个红外类,使用两栖类来作为参数,然后使用红外类的shot方法,那么这个shot即包含两栖功能又包含红外功能,并且还使用原来的shot功能。这里就是组合多种功能,也就是说使用多种功能来装饰tank。

Decorator模式的几个要点

  •  通过采用组合、而非继承的手法, Decorator模式实现了在运行时动态地扩展对象功能的能力,而且可以根据需要扩展多个功能。避免了单独使用继承带来的“灵活性差”和“多子类衍生问题”。
  •  Component类在Decorator模式中充当抽象接口的角色,不应该去实现具体的行为。而且Decorator类对于Component类应该透明——换言之Component类无需知道Decorator类,Decorator类是从外部来扩展Component类的功能。
  •  Decorator类在接口上表现为is-a Component的继承关系,即Decorator类继承了Component类所具有的接口。但在实现上又表现为has-a Component的组合关系,即Decorator类又使用了另外一个Component类。我们可以使用一个或者多个Decorator对象来“装饰”一个Component对象,且装饰后的对象仍然是一个Component对象。
  •  Decorator模式并非解决“多子类衍生的多继承”问题,Decorator模式应用的要点在于解决“主体类在多个方向上的扩展功能”——是为“装饰”的含义。有点类似Bridge模式,但是Bridge桥接模式中的多维度的变化给人感觉一种“撕裂对象抽象”的感觉,通俗点讲就是将一个对象设计成这这样的接口不合适,设计成那样的接口也不合适,那么怎么办?分离!Decorator装饰模式中的功能扩展的变化不会撕裂接口(也就是说接口是稳定的),而是一级一级地向下(纵向)扩展接口,同时有叠加的效应(比如想同时获得多种功能扩展),这时候怎么办?横向扩展,也就是装饰!

在.net中Decorator模式的典型使用就是一系列的Stream类,作为实体类的有FileStream、NetworkStream、MemoryStream等,作为扩展功能接口的有BufferedStream、CryptoStream等。但是在Stream的扩展功能接口中是没有类似Decorator基类的,他是在每个功能类中自己保存一个Stream实体对象,在方法中直接调用Stream实体对象的方法。

【飞控】PX4 Autopilots与MATLAB/Simulink联合仿真环境搭建全攻略 本文详细介绍了在Windows系统上搭建PX4 Autopilots与MATLAB/Simulink联合仿真环境的完整流程。通过WSL2安装Ubuntu,配置UAV Toolbox支持包,并重点解决了PX4源码克隆、子模块更新等网络难题,最终实现软件在环(SITL)仿真。文章还涵盖了硬件在环(HITL)配置及常见问题排查,为无人机飞控算法开发与测试提供了高效、可靠的解决方案。 阅读详情

相关推荐

大疆OcuSync系统背后的黑科技:跳频扩频技术如何让你的无人机飞得更稳

本文深入解析了大疆OcuSync系统如何运用跳频扩频技术等先进无线通信方案,显著提升无人机在复杂环境下的飞行稳定性。系统通过跳频扩频与直接序列扩频技术协同工作,结合双频智能切换与多天线MIMO,有效对抗信号干扰与多径效应,确保控制指令与高清图传的可靠、低延迟传输,为用户带来更安心、更流畅的飞行体验。

ol7890123的博客 627

《C#面向对象设计模式纵横谈》——10、Decorator装饰模式(结构型模式)|第十讲

应用场景描述:假如我们需要为游戏中开发一种坦克,除了各种不同类型的坦克外,我们还希望在不同的场合中为其增加以下一种或多种功能,比如红外线夜视功能,比如水陆两栖功能,比如卫星定位功能等;   一般情况下,我们在编程时可能这样做: //定义坦克的抽象类 public abstract class Tank{     public abstract shot();    public abs...

weixin_33775582的博客 95

关于SVPWM七段式五段式调制后的相电压和线电压波形——大疆DJI技术笔试

1.SVPWM七段式/五段式调制的相电压和线电压波形 脉宽调制(PWM)在并网变流技术中得到了广泛的应用。与正弦脉宽调制(SPWM)的控制方法相比,SVPWM方法具有直流侧电压利用率高,电压谐波小,易于数字化实现等显著的优点,从而使SVPWM在实际的应用中越来越普遍。TMS320F28335是32位浮点的DSP控制器,具有150MHz的高速处理能力,18路PWM输出,与前几代数字信号控制器相比,性能平均提高了50%。其中具体的SVPWM理论实现的原理,请参考我的博客永磁同步电机的矢量控制策略(七)一一一SV

昔时扬尘处 2万+

WPF 的 Adorner、Decorator 和 AdornerDecorator

Decorator 和 Adorner   它们都有“装饰品”的意思。   Decorator类负责包装某个UI元素,以提供额外的行为。它有一个类型为UIElement的Child属性,其中含有待包装的内容。Decorator可被用于添加简单的视觉装饰,例如边界(Border),或者更复杂的行为,例如ViewBox,AdornerDecorator,或是InkPresenter。

yulongguiziyao的专栏 7721

RTT(RT-Thread)串口设备(RTT保姆级教程)

本章主要介绍串口设备在RT-Thread操作系统中应用层如何使用。关于串口设备的使用,我们只需要在应用层找到串口设备,然后去初始化,初始化完成以后就可以读写串口设备了。操作的方法在应用层,驱动是不需要我们去完成的,驱动已经在操作系统中提供了。

qq_25218501的博客 1万+

Oracle登录报错ORA-12560?5分钟搞定TNS协议适配器错误的完整修复指南

本文详细解析了Oracle登录报错ORA-12560(TNS协议适配器错误)的成因与解决方案。从基础服务检查到高级网络配置排查,提供了一套完整的修复流程,帮助数据库管理员快速解决连接问题,确保Oracle数据库的稳定运行。

weixin_29278805的博客 519

09 SAP CPI 访问公共API接口

我在网上找了一个公共API,入参输入汉字返回拼音。至此,一个真正的访问API的接口就做好了。点击保存时可看到红叉报错。

SAP CPI 477

WPF - Adorner

  看到这个标题,您可能会在脑中产生一个疑问:Adorner是什么?Adorner是WPF窗口中独立的一层,支持在界面元素之上执行独立的绘制及用户交互。可以说,Adorner在您的WPF程序中无处不在。在WPF中,从编辑框控件中光标的显示和选中效果的支持,到具有数据焦点的控件所具有的虚线外框,都是通过Adorner实现的。 什么是Adorner   鉴于您可能不熟悉Adorne...

weixin_30906425的博客 442

RT-DETR-R18 上下文信息融合:引入全局特征提升遮挡目标检测

"""轻量化全局特征提取器(2层Transformer编码器)"""# 特征投影层(将多尺度特征统一维度)# 轻量化Transformer编码器(分组卷积优化)# 全局特征池化(输出 [bs, hidden_dim])# local_features: 多尺度特征列表 [C3, C4, C5],各 [bs, c, h, w]# 统一投影至 hidden_dim 并展平为序列# Transformer编码全局上下文# 全局池化得到全局向量。

走向CTO的路上... 494

华为OD机试 - 学校的位置 - 数学问题(Python/JS/C/C++ 2024 B卷 100分)

华为OD机试 2024E卷题库疯狂收录中,刷题。

学Java,找哪吒 455

C#面向对象设计模式纵横谈

http://115.com/file/bhifcm6d# C#面向对象设计模式纵横谈(1):面向对象设计模式与原则.rar http://115.com/file/bhifcvb4# C#面向对象设计模式纵横谈(2):Singleton_单件(创建型模式).rar http://115.com/file/aqky0l4l# C#面向对象设计模式纵横谈(3):Abs...

weixin_34152820的博客 173

CQE和SQE 以及 PQA和DQA的区别

‌:PQA聚焦产品全生命周期流程管理,DQA专注于设计阶段的质量控制。

a1809032425的博客 1900

C#面向对象设计模式纵横谈系列课程

C#面向对象设计模式纵横谈(1):面向对象设计模式与原则 (Level 300) 讲  师:李建忠 课程简介:本培训课程从总体介绍面向对象设计模式的基本概念和原则,并演示面向对象设计模式在.NET框架程序设计中的实践应用。 推荐指数: C#面向对象设计模式纵横谈(2):Singleton 单件(创建型模式) (Level 300) 讲  师:李建忠 课程简介:本培训课程探讨GoF...

weixin_30518397的博客 79

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

设计模式之装饰模式 c++实现和详细分析

Decorator模式(别名Wrapper):动态将职责附加到对象上,若要扩展功能,装饰者提供了比继承更具弹性的代替方案。

hnust_xiehonghao的专栏 3841

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

[导入]C#面向对象设计模式纵横谈(10):Decorator 装饰模式(结构型模式).zip(9.84 MB)...

讲座内容: 本培训课程探讨GoF23之Decorator 装饰模式的意图、动因、原理、应用场景与C#语言实现,以及该模式在.NET框架程序设计中的具体应用。 课程讲师: 李建忠 上海祝成信息科技有限公司 高级培训讲师 MSDN特邀讲师 .NET技术专家,C++/CLI 专栏作家。南京邮电学院毕业,历任程序员,高级程序员,开发主管。现为上海祝成科技软件架构师,高级培训讲师。译著Microso...

weixin_30760895的博客 69

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

[转载] C#面向对象设计模式纵横谈——10. Decorator装饰模式

主讲:李建忠 来源:http://www.microsoft.com/china/msdn/events/webcasts/shared/webcast/consyscourse/CsharpOOD.aspx Decoratorpublic class Tank { abstract void Shot(); abstract ...

weixin_30256505的博客 112

C#面向对象设计模式纵横谈汇总

1. 面向对象设计模式及原则 创建型模式------------------------------------------------------------------- 2. Singleton单件模式 3. Abstract Factory抽象工厂模式 4. Builder生成器模式 5. Factory Method工厂方法模式 6. Prototype原型模式 ...

weixin_30886233的博客 78

Linux进程控制本质:从fork到waitpid的内核级生命周期解析

进程是操作系统资源分配的基本单位,其创建、执行与终止涉及内核调度、内存管理与信号处理等核心机制。理解fork()的写时复制(COW)原理、exit()与_exit()在用户态清理和内核终结层面的关键差异,以及waitpid()如何协同SIGCHLD完成资源回收,是构建稳定服务的基础。这些机制共同支撑守护进程、预派生模型及systemd socket activation等工业实践。本文深入task_struct生命周期、文件描述符共享陷阱、僵尸进程成因与四层防御体系,聚焦Linux进程控制中最具工程价值的三

weixin_34090562的博客 379

GOF《设计模式》摘录

一、设计模式概述 http://hotsoho.net.cnblogs.com/articles/328646.html二、Singleton 单件(创建型模式) http://hotsoho.net.cnblogs.com/articles/328616.html三、Abstract Factory 抽象工厂模式(创建型模式) http:/...

Anna_0110的博客 99

详解Adorner Layer

首先,千万不要觉得Adorner离你很远,因为最简单的WPF界面也会用到Adorner。在WPF中,下面的几个很常见的功能,都是用Adorner实现的。     1. 光标(caret)     2. 焦点(focus)     3. 高亮(highlight)     4. 拖拽预览(drag and drop)     5. 拼写错误提示     6. 数据绑定中用来提示错误的Er...

weixin_33705053的博客 401

C#面向对象设计模式纵横谈 学习笔记16 Interpreter 解释器模式(行为型模式)

Interpreter模式是一种比较不常用的模式,因为这种模式存在一些弊端,他的使用有很大的条件限制。Interpreter是一种特殊的设计模式,它建立一个解释器,对于特定的计算机程序设计语言,用来解释预先定义的文法。简单地说,Interpreter模式是一种简单的语法解释器构架。先借用李建忠老师的代码例子  public class Program    {        s

Lawrence的专栏 1714
上一篇: Asp.Net Ajax 学习笔记22 使用Microsoft Ajax Library中的浏览器兼容功能
下一篇: Asp.Net Ajax 学习笔记23 利用Microsoft AJAX Library开发客户端组件(上)
firewolffeng
博客等级 码龄22年 29粉丝 66原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值