装饰模式

JAVA23种设计模式之一,英文叫Decorator Pattern,又叫装饰者模式。装饰模式是在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能.

 1、装饰模式与类继承的区别:

1)    装饰模式是一种动态行为,对已经存在类进行随意组合,而类的继承是一种静态的行为,一个类定义成什么样的,该类的对象便具有什么样的功能,无法动态的改变。

  所谓动态是说可以在系统运行时(RunTime)动态给对象增加其它职责而不需要修改代码或重新编译;所谓静态是说必须通过调整代码(DesignTime)才能给对象增加职责,而且系统还需要重新编译;从具体技术层面来说,对象的组合和继承正好对应于前面的动态和静态,因为通过对象组合建立的交互关系不是在代码中(DesignTime)固定死的,而是在运行时(RunTime)动态组合的;而通过继承建立的关系是僵硬的难以改变的,因为它是在代码中(DesignTime)固定死了的,根本不存在运行时(RunTime)改变的可能。换个角度说:我们应该多使用对象组合来保持系统的运行时扩展性,尽量少使继承。

2)    装饰模式扩展的是对象的功能,不需要增加类的数量,而类继承扩展是类的功能,在继承的关系中,如果我们想增加一个对象的功能,我们只能通过继承关系,在子类中增加两个方法

2、  装饰模式的特点:

1)    装饰对象和真实对象具有相同的接口,这样客户端对象就可以以真实对象的相同的方式和装饰对象交互。

2)    装饰对象包含一个真实对象的引用(reference).

3)    装饰对象接受所有来自客户端的请求,它把这些请求转发给真实的对象。

4)    装饰对象可以在转发这些请求以前或者以后增加一些附加的功能。这样就能确保在运行时,不用修改给定对象结构就可以在外部增加附加的功能。在面向对象的程序设计中,通常是使用继承的关系来扩展给定类的功能

3、装饰模式的实现:

 

clip_image002 

Component:

定义一个对象接口,可以给这些对象动态地添加职责。

public interface Component
{void operation();
}

Concrete Component:

定义一个对象,可以给这个对象添加一些职责。

public class ConcreteComponent implements Component
{public void operation(){// Write your code here}
}

 Decorator:

维持一个指向Component对象的引用,并定义一个与 Component接口一致的接口。

public class Decorator implements Component
{public Decorator(Component component){this.component = component;}public void operation(){component.operation();}private Component component;
}

 Concrete Decorator:

在Concrete Component的行为之前或之后,加上自己的行为,以“贴上”附加的职责。

public class ConcreteDecorator extends Decorator
{public void operation(){//addBehavior也可以在前面super.operation();addBehavior();}private void addBehavior(){//your code}
}
public class Client
{   
  public static void main(String[] args)   
  {    
       Component component = new ConcreteDecorate(new ConcreteComponent());     
     component.doSomething();   
  }
}
 

1. 如果只有一个Concrete Component类而没有抽象的Component接口时,可以让Decorator继承Concrete Component。

clip_image004

2. 如果只有一个Concrete Decorator类时,可以将Decorator和Concrete Decorator合并。

clip_image006 

 Decorator是装饰者模式里非常特殊的一个类,它既继承于Component【IS A关系】,又维护一个指向Component实例的引用【HAS A关系】,换个角度来说,Decorator跟Component之间,既有动态组合关系又有静态继承关系,WHY? 这里为什么要这么来设计?上面我们说过,组合的好处是可以在运行时给对象增加职责,Decorator【HAS A】Component的目的是让ConcreteDecorator可以在运行时动态给ConcreteComponent增加职责,这一点相对来说还比较好理解;那么Decorator继承于Component的目的是什么?在这里,继承的目的只有一个,那就是可以统一装饰者和被装饰者的接口,换个角度来说,不管是ConcretComponent还是ConcreteDecorator,它们都是 Component,用户代码可以把它们统一看作Component来处理,这样带来的更深一层的好处就是,装饰者对象对被装饰者对象的功能职责扩展对用户代码来说是完全透明的,因为用户代码引用的都是Component,所以就不会因为被装饰者对象在被装饰后,引用它的用户代码发生错误,实际上不会有任何影响,因为装饰前后,用户代码引用的都是Component类型的对象,这真是太完美了!装饰者模式通过继承实现统一了装饰者和被装饰者的接口,通过组合获得了在运行时动态扩展被装饰者对象的能力。

给一个对象动态添加额外职责,这些职责需要由用户决定加入的方式和时机。装饰模式提供了“即插即用”的方式,在运行期间决定何时增加何种功能。就增加功能来说,装饰模式比生成子类更加灵活。

转载于:https://www.cnblogs.com/muyuhu/archive/2013/04/29/3050346.html

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

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

相关文章

Win11安卓极速教程!

适用于 Android 的 Windows 子系统(以下简称“WSA”)使你的 Windows 11 电脑能够运行 Android 应用。※ 如何在 Windows 11 上运行 Android 应用此前的教程较为详细,但也繁琐,尤其是 adb 部署部分,不适合新手入门&…

ubuntu12.04 使用gedit 打开txt文件中文乱码的处理方法

2019独角兽企业重金招聘Python工程师标准>>> gedit --encodingGB18030 filename.txt 转载于:https://my.oschina.net/zhangdapeng89/blog/58965

js与jsp

在JS代码片段中&#xff0c;通过<%request.getParameter("username")%> 访问了Login.jsp中表单传递过来的username属性的值&#xff0c;这样的操作上没有问题的。如果想要把getUserName()方法放在一个单独的Js中&#xff0c;如Welcome.js&#xff0c;也就是不在…

你最擅长哪种数学思维?

全世界只有3.14 % 的人关注了爆炸吧知识许多人会抱怨说&#xff0c;自己没有“数学头脑”。事实上&#xff0c;数学家会以各种各样的方式思考&#xff0c;根本没有所谓的哪种思考数学的方式是正确的。但这很可能造成沟通上的障碍&#xff0c;试想一下&#xff0c;一个用视觉图像…

Hive中视图机制的初步使用及分析

作者: 大圆那些事 | 文章可以转载&#xff0c;请以超链接形式标明文章原始出处和作者信息 网址: http://www.cnblogs.com/panfeng412/archive/2013/04/29/hive-view-usage-and-analysis.html 本文是对Hive中逻辑视图的介绍&#xff0c;通过一个简单的视图例子&#xff0c;说明其…

励志!送女儿去厦大读研后,爸爸回家就考了厦大的博士,现在是女儿的“学弟”...

全世界只有3.14 % 的人关注了爆炸吧知识2020上半年&#xff0c;在安徽阜阳家里&#xff0c;女儿王睿在房间内上着厦门大学在线专业课&#xff0c;父亲王健作为师范高校教师直播着自己的思政公共课和生命教育有关课程。然而一到周末&#xff0c;王健也和女儿一样&#xff0c;作为…

【cocos2d-js官方文档】二十五、Cocos2d-JS v3.0中的单例对象

为何将单例模式移除 在Cocos2d-JS v3.0之前。全部API差点儿都是从Cocos2d-x中移植过来的&#xff0c;这是Cocos2d生态圈统一性的重要一环。可惜的是&#xff0c;这样的统一性也在非常大程度上限制了Cocos2d-html5的发展&#xff0c;有一些在C中非常有意义的涉及搬到Html5平台后…

mysql 中有什么命令_常用mysql命令大全

常用的MySQL命令大全连接MySQL格式&#xff1a; mysql -h主机地址 -u用户名 &#xff0d;p用户密码1、例1&#xff1a;连接到本机上的MYSQL。首先在打开DOS窗口&#xff0c;然后进入目录 mysqlbin&#xff0c;再键入命令mysql -uroot -p&#xff0c;回车后提示你输密码&#xf…

Android之webview背景设置为透明无效

Adndroid 2.X的设置 webview是一个使用方便、功能强大的控件&#xff0c;但由于webview的背景颜色默认是白色&#xff0c;在一些场合下会显得很突兀&#xff08;比如背景是黑色&#xff09;。 此时就想到了要把webview的背景设置为透明&#xff0c;这样就可以与其背景融为一体…

linux系统的运行级别

linux 运行级别 0 停机1 单用户模式&#xff0c;用来维护系统。2.多用户不能使用NFS模式。3 多用户模式&#xff0c;也是主要的使用模式4 未定义5 窗口使用模式6 重新启动模式用init(0 1 2 3 4 5 6)切换运行级别&#xff0c;&#xff08;init 3 切换到多用户模式&#xff09;转…

C# WPF MVVM模式Prism框架从零搭建(经典)

01—前言目前最新的PRISM的版本是8.1.97&#xff0c;本节以6.3.0.0 讲解&#xff0c;可以在Github上获取PRISM的源码。Prism Github地址&#xff1a;https://github.com/PrismLibrary/PrismPrism官方文档&#xff1a;https://prismlibrary.com/docs/Prism要用到IOC容器&#xf…

在中国,有这样一些村落

全世界只有3.14 % 的人关注了爆炸吧知识01地坑村在河南有一个全球最神奇的村落这村子神奇就神奇在当你走进村子能听到家家户户的吵闹声却见不到一座房子原来村落居然建在地底下基本不用与外界接触但村子却被外国媒体争相报道火的一塌糊涂更不可思议的是村里的老人平均寿命都超1…

2-2

为方便储户&#xff0c;某银行拟开发计算机储蓄系统。储户填写的存款单或取款单由业务员输入系统&#xff0c;如果是存款&#xff0c;系统记录存款人姓名、住址、存款类型、存款日期、利率等信息&#xff0c;并印出存款单给储户&#xff1b;如果是取款&#xff0c;系统计算利息…

.NET 6新特性试用 | 隐式using指令

前言在使用《最小Web API》时&#xff0c;我们发现&#xff0c;相比以前的代码&#xff0c;大量的using指令消失了&#xff1a;using指令的主要作用是允许使用在命名空间中定义的类型&#xff0c;而无需指定该类型的完全限定命名空间。那么&#xff0c;在.NET 6下为什么不需要了…

mysql 导入文件夹_MySQL-导入与导出

CSV文件导入MySQLLOAD DATA INFILE语句允许您从文本文件读取数据&#xff0c;并将文件的数据快速导入数据库的表中。导入文件操作之前&#xff0c;需要准备以下内容&#xff1a;一、将要导入文件的数据对应的数据库表。二、准备好一个CSV文件&#xff0c;其数据与表的列数和每列…

Android之ButterKnife--View注入框架

俗话说:“不会偷懒的程序员不是好的程序员!”。作为一名Android开发,是不是经常厌烦了大量的findViewById以及setOnClickListener代码,而ButterKnife是一个专注于Android系统的View注入框架,让你从此从这些烦人臃肿的代码中解脱出来。先来看一段代码示例说明下ButterKnife…

设计模式 - Mediator

意图&#xff1a;用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用&#xff0c;从而使其耦合松散&#xff0c;而且可以独立地改变它们之间的交互。 一般来说&#xff0c;只有对于那种同事类之间是网状结构的关系&#xff0c;才会考虑使用中介者模式。…

6部有生之年必看的BBC “教材级” 地理纪录片,免费领取!

看BBC的纪录片&#xff0c;既可以追溯上下数千年的历史文化&#xff0c;也可以欣赏从宇宙到地心深处的奇妙境界&#xff0c;而及其超级精彩的画面即使定格&#xff0c;也是一幅摄影佳作。BBC纪录片题材广泛、制作精良&#xff0c;观看起来算的上是赏心悦目。对于学习英文&#…

Android之开发中用到的几个多线程解析

在开发工程中线程可以帮助我们提高运行速度,Android开发中我知道的线程有四个一个是老生长谈的Thread,第二个是asyncTask,第三个:TimetTask,第四个是Looper,四个多线程各有个的有点,Thread的运行速度是最快的,AsyncTask的规范性是最棒的,其它两个也有自己的优点,下面先贴…

blazor wasm开发chrome插件

用blazor(Wasm)开发了一个chrome插件感觉效率挺高的&#xff0c;分享给大家先简单介绍下WebAssembly的原理&#xff1a;“WebAssembly是一种用于基于堆栈的虚拟机的二进制指令格式”image如上图&#xff0c;浏览器在执行js时是会经历 Parser转成语法树->Compiler转成字节码-…