设计模式之装饰器

装饰器模式介绍

俄罗斯套娃

装饰器的核心就是在不改原有类的基础上给类新增功能。可以避免继承导致的子类过多,可避免AOP带来的复杂性。

装饰器主要解决的是直接继承下因功能的不断横向扩展导致子类膨胀的问题,而是用装饰器模式后就会比直接继承显得更加灵活同时这样也就不再需要考虑子类的维护。

在实现的过程中,具体实现只关心扩展部分的功能,同时不会影响原有类的核心服务,也不会因为使用继承方式而导致的多余子类,增加了整体的灵活性。

装饰器模式满足单一职责原则,可以在自己的装饰类中完成功能逻辑的扩展,而不影响主类,同时可以按需在运行时添加和删除这部分逻辑。另外装饰器模式与继承父类重写方法,在某些时候需要按需选择,并不一定某一个就是最好。

装饰器实现的重点是对抽象类继承接口方法的使用,同时设定被继承的接口可以通过构造函数传递其实现类,由此增加扩展性并重写方法里可以实现此部分父类实现的功能。

封装器是一个能与其他目标对象连接的对象。封装器包含与目标对象相同的一系列方法,它会将所有接收到的请求委派给目标对象,但是封装器可以在将请求委派给目标前后对其进行处理,所以可能会改变最终结果。

装饰模式由于目标对象和装饰器遵循同一接口,因此你可用装饰来对对象进行无限次的封装,结果对象将获得所有封装器叠加而来的行为。

装饰器模式的抽象点

  • 抽象构件角色-定义抽象接口

  • 具体构件角色-实现抽象接口,可以是一组

  • 装饰角色-定义抽象类并继承接口中的方法,保证一致性

  • 具体装饰角色-扩展装饰具体的实现逻辑


继承可能引发的几个严重问题:

1、继承是静态的。你无法在运行时更改已有对象的行为,只能使用由不同子类创建的对象来替代当前的整个对象。

2、子类只能有一个父类。大部分编程语言不支持多继承。

装饰器结构

  • 部件  声明封装器和被封装对象的公用接口。

  • 具体部件  类是被封装对象所属的类,它定义了基础行为,但装饰类可以改变这些行为。

  • 基础装饰  类拥有一个指向被封装对象的引用成员变量。该变量的类型应当被声明为通用部件接口,这样它就可以引用具体的部件和装饰。装饰基类会将所有操作委派给被封装的对象。

  • 具体装饰类  定义了可动态添加到部件的额外行为。具体装饰类会重写装饰基类的方法,并在调用父类方法之前或之后进行额外的行为。

  • 客户端  可以使用多层装饰来封装部件,只要它能使用通用接口与所有对象交互即可。

适用场景

1、在无需修改代码的情况下即可使用对象,且希望在运行时为对象新增额外的行为,可以使用装饰模式。

装饰能将业务逻辑组织为层次结构,你可为各层创建一个装饰,在运行时将各种不同逻辑组成对象,由于这些对象都遵循通用接口,客户端代码能以相同的方式使用这些对象。

2、当某些业务无法使用继承来扩展对象行为时,可以使用装饰模式。

装饰器模式优缺点

优点:

  • 你需要创建新子类即可扩展对象的行为。

  • 可在运行时添加或删除对象的功能。

  • 可以用多个装饰封装对象来组合几种行为。

  • 满足单一职责原则。

缺点:

  • 在封装器栈中删除特定封装器比较困难

  • 实现行为不受装饰栈顺序影响的装饰比较困难

  • 刚开始各层的初始化配置代码比较糟糕

Demo

    /// <summary>/// 组件/// </summary>public abstract class Component{public abstract string Operation();}
}
    /// <summary>/// 抽象的装饰者/// </summary>class ConcreteComponent:Component{public override string Operation(){return "ConcreteComponent";}}
    abstract class Decorator:Component{protected Component _component;public Decorator(Component component){this._component = component;}public void SetComponent(Component component) {this._component = component;}public override string Operation(){if (this._component!=null){return this._component.Operation();}else{return string.Empty;}}}
    class ConcreteDecoratorA : Decorator{public ConcreteDecoratorA(Component comp):base(comp){}public override string Operation(){return "ConcreteDecoratorA " + base.Operation();}}class ConcreteDecoratorB:Decorator{public ConcreteDecoratorB(Component comp): base(comp){}public override string Operation(){return "ConcreteDecoratorA " + base.Operation();}}    
    public class Client{public void ClientCode(Component component) {Console.WriteLine("Result:"+component.Operation());}}
    class Program{static void Main(string[] args){Client client = new Client();var temp = new ConcreteComponent();Console.WriteLine("Start------");Console.WriteLine();ConcreteDecoratorA d1 = new ConcreteDecoratorA(temp);ConcreteDecoratorB d2 = new ConcreteDecoratorB(d1);Console.WriteLine("Start Music");client.ClientCode(d2);Console.ReadKey();}}
计算结果

其实可以看出装饰器模式和组合模式还是有异曲同工之处的,装饰器模式是对既有类中方法的可重写,也就是可以改变其方法的结构,而组合则是不能改变其既有类中的方法,只能将其组合成想要实现的样子。

小寄语

人生短暂,我不想去追求自己看不见的,我只想抓住我能看的见的。

我是阿辉,感谢您的阅读,如果对你有帮助,麻烦点赞、转发  谢谢。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/299768.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

zookeeper集群部署监控与选举同步流程等工作原理

部署一个zookeeper集群&#xff0c;要多简单就能有多简单&#xff08;下载压缩包&#xff0c;解压&#xff0c;修改配置文件zoo.cfg,执行启动脚本&#xff09;&#xff0c;但是想要真的把这套东西玩好了&#xff0c;还是需要费些功夫研究一番的。就跟自己搭建一个lnmp的站点&am…

手把手教出欧拉!数学界最伟大的老师惨遭全网歪曲抹黑,奇葩说陈铭一句话揭露真相.........

全世界只有3.14 % 的人关注了青少年数学之旅说到伟大的老师你首先想到的是谁&#xff1f;万世师表的孔子&#xff1f;古代先哲亚里士多德&#xff1f;支援山区的青年教师&#xff1f;还是高三时每天在你耳边督促你订正错题本的班主任&#xff1f;在这个光荣的行列中&#xff0c…

Hello Blazor:(8)启用深色模式

前言上次&#xff0c;在“集成Tailwind CSS”时&#xff0c;我发现tailwind.config.js配置文件有这样一个选项&#xff1a;darkMode: false, // or media or class查看官方文档&#xff0c;原来这是用来启用深色模式的配置。既然深色模式几乎成了所有网站和软件的标配&#xff…

超越Linux!华为鸿蒙明年将成“第五大操作系统”,网友:何时超过iOS?

全世界只有3.14 % 的人关注了青少年数学之旅今年8月的华为开发者大会上&#xff0c;鸿蒙OS正式亮相&#xff0c;这是全世界第一个基于微内核的全场景分布式操作系统。余承东曾表示&#xff1a;华为手机优先使用安卓生态&#xff0c;一旦受实体名单影响安卓不能用&#xff0c;一…

关于 .NET 与 JAVA 在 JIT 编译上的一些差异

最近因为公司的一些原因&#xff0c;我也开始学习一些 JAVA 的知识。虽然我一直是以 .NET 语言为主的程序员&#xff0c;但是我并不排斥任何其它语言。在此并不讨论 JAVA .NET 的好坏&#xff0c;仅仅是对 .NET 跟 JAVA 程序的编译执行过程进行一些简单的介绍跟比较。因为有些内…

在鹅厂,我作为一个Java 程序员每天都在摸鱼!!!

作为一名 在大、中、小微企业都待过 的 Java 开发者&#xff0c;今天和大家分享下自己在不同公司的工作日常和收获。包括一些个人积累的工作提升经验&#xff0c;以及一些 Java 学习的方法和资源。 先从我的第一份 Java 开发实习工作说起吧~ 实习生工作日常 我是在大二暑期开…

心中一万只草泥马在奔腾是种怎样的体验?| 今日最佳

全世界只有3.14 % 的人关注了青少年数学之旅&#xff08;图源横店街道办主任&#xff0c;侵权删&#xff09;

iOS工程中的info.plist文件的完整研究

原地址&#xff1a;http://blog.sina.com.cn/s/blog_947c4a9f0100zf41.html 们建立一个工程后&#xff0c;会在Supporting files下面看到一个"工程名-Info.plist"的文件&#xff0c;这个是对工程做一些运行期配置的文件&#xff0c;很重要&#xff0c;不能删除。 如果…

不会自动化UI测试?不会编程?没问题,会造句就行!

上次&#xff0c;我们介绍了用于Web应用程序自动化测试的工具Playwright for .NET。但是直接使用它来编写测试用例&#xff0c;代码比较凌乱&#xff0c;后期也不好维护。因此&#xff0c;我们利用SpecFlow让测试用例更好理解和维护。1.SpecFlow介绍SpecFlow是.Net平台下用于行…

鼠标手势识别 [Flash]

算法&#xff1a;演示&#xff1a;源代码&#xff1a;http://www.foxaweb.com/demos/mousegesture/mouse_gesture_v1_0.zip转载于:https://www.cnblogs.com/boringlamb/archive/2008/05/20/1203115.html

Java交流|面试最后一问:你有什么问题想问我吗?

尽管&#xff0c;我们之前做了这么多的面试准备&#xff0c;然而&#xff0c;最后这个90%可见的最后一问可能直接让你功亏一篑。这么厉害的最后一问&#xff1a;”你有什么问题想问我吗&#xff1f;“ 看似平淡无奇的问题&#xff0c;但是却蕴含着多方面的含义。这个问题表面上…

基于MapWinGis的开发探索(三)--改善缩放、渲染、显示文本

继续对MapWinGis进行研究探索&#xff0c;紧接上一篇文章。MapWinGis自身有很多功能&#xff0c;此篇主要也是基于其内在方法来写的。除了第二点显示文本是根据其源代码进行扩展的。原图:一、改善缩放功能上一版本放大缩小都必须点击下工具栏的放大、缩小。是鼠标处于缩放状态&…

T-SQL利用Row_Number函数实现分页

SQL: CREATE PROCEDURE PagingViewTest (currentPageIndex INT, --页序号pageSize INT, --页大小pageCount INT OUTPUT --返回值&#xff0c;总记录数 ) AS BEGIN--取总记录数 SELECT pageCountCOUNT(OrderID) FROM dbo.sale_Order; --利用CTE以提高执行效率 WITH Result AS (…

程序员没有女朋友的原因,我终于找到了!

全世界只有3.14 % 的人关注了青少年数学之旅程序员没有女朋友的原因▼程序员大脑里想的▼每天要学习太多语言&#xff0c;程序员太忙了▼女朋友 VS 编译器▼程序员sao起来&#xff0c;还需要女朋友吗&#xff1f;▼电脑才是程序员的女朋友▼互道晚安后&#xff0c;会不会偶遇在…

dotNet 5 中执行 Node.js

在低代码产品中为了扩展功能&#xff0c;我们在业务编排中会扩展代码块的功能&#xff0c;允许用户直接在界面中进行代码&#xff08;Node.js、 Python&#xff09;的编写&#xff0c;来实现取数或者赋值的一些功能。本文简单介绍下在 dotNET 5 中怎么样进行 Node.js 的调用以及…

为什么会有蟑螂这种反人类的动物出现?

全世界只有3.14 % 的人关注了青少年数学之旅相信很多人都听过南北蟑螂的故事&#xff0c;即使是一个可以打死老虎的北方人在南方蟑螂面前也会惊慌失措。除此之外&#xff0c;我们日常生活里和蟑螂的故事还有很多&#xff0c;比如&#xff1a;当你打开灯的时候&#xff0c;会有一…

Ajax使用初步

Ajax定义为“Asynchronous JavaScript XML”的简称&#xff0c;也就是异步的JavaScript和XML处理。从原理上看&#xff0c;主要是Ajax可以通过调用HttpRequest实现与服务器的异步通讯&#xff0c;并最终在网页中实现丰富友好的用户界面Ajax使用初步&#xff0c;配置步骤1.把Aj…

WPF 如何流畅地滚动ScrollViewer

WPF开发者QQ群&#xff1a; 340500857 | 微信群 -> 进入公众号主页 加入组织欢迎转发、分享、点赞、在看&#xff0c;谢谢~。 前言看了看原生UWP的ScrollViewer&#xff0c;滑动很流畅(例如 开始菜单)&#xff0c;但是WPF自带的ScrollViewer滚动十分生硬..突发奇想&#x…

10岁吊打职业教师的天才,仅用10篇论文称霸数学界160多年,40岁英年早逝却迄今无人超越...

全世界只有3.14 % 的人关注了青少年数学之旅今天超模君就给大家讲讲黎曼。人类历史上最伟大的数学天才的德国数学家是十九世纪数学界的巅峰——节选自《数学之旅 闪耀人类的54个数学家》1826年&#xff0c;黎曼作为家中的老二在德国汉诺威的布雷斯伦茨村出生了。他的父亲是村里…

面试可以,但别打扰我睡觉! | 今日最佳

全世界只有3.14 % 的人关注了青少年数学之旅&#xff08;图源科技九洲君&#xff0c;侵权删&#xff09;