装饰器模式(Decorator)[转载]

【Linux系统】Kdenlive软件多机位同音频视频同步化处理 Kdenlive简介 官网链接:https://kdenlive.org/zh/ 命令行安装: apt-get install kdenlive Kdenlive能够进行多轨道视频编辑,可以使用和调整多条音频、视频轨道。每条轨道可以按需进行单独锁定、静音。 Kdenlive多机位同音频视频同步化处理步骤 1. 新建Kdenlive文件 选择<文件>-<新建>,建立新的kdenlive文件,初始设置为<视频轨:2>,<音频轨:2>。 视. 阅读详情

  Decorator设计模式是典型的结构型模式(在GOF的那本模式的Bible中将模式分为:1.创建型模式;2.结构型模式;3.行为模式三种)。它的主要用意是:动态地为对象添加一些额外的功能。(记住上面两种颜色的词汇,理解装饰器模式的精髓所在!)下面是GOF的《Element of reusable Object-Oriented Software》中对Decorator用意的概述:

Decorator Pattern――Attaches additional responsibilities to an object dynamically . Decorators provide a flexible alternative to subclassing for extending functionality .

1 何时需要使用装饰器模式

       GOF的那本Bible中关于装饰器模式列举的是一个文本组件与边框的例子(在这里我就不举了,主要是因为我会在书中举一个相似的,但却非常有说服力的例子,它对Swing中的某些本来应该使用Decorator却没有使用的对象的改进。同时会提出内包装、外包装的概念。看到这个例子后大家仔细体会吧!通过例子告诉大家一点:任何设计不是一成不变的、模式的应用是极其灵活的……)。下面我举一个“三明治”的例子!

       很多人都吃过三明治(我除外!“没吃过猪肉,俺可听过猪叫”),都会知道三明治必不可少的是两块面包片,然后可以在夹层里加上蔬菜、沙拉、咸肉等等,外面可以涂上奶油之类的。假如现在你要为一个三明治小店构造一个程序,其中要设计各种三明治的对象。可能你已经创建了一个简单的Sandwich对象,现在要产生带蔬菜的就是继承原有的Sandwich添加一个蔬菜的成员变量,看起来很“正点”的做法,以后我还要带咸肉的、带奶油的、带蔬菜的又分为带青菜的、带芹菜的、生菜的……还是一个一个继承是吧!假如我们还需要即带蔬菜又带其它肉类,设置我们还要求这些添加成分的任意组合,那你就慢慢继承吧!

       读过几年书的会下面这个算术,我们有n种成分,在做三明治的时候任意搭配,那么有多少种方案呢?!算算吧!你会有惊人的发现。N种成分,什么都不要是Cn0种方案吧!要1种是Cn1吧!…..要n种是Cnn吧!加起来不就是吗?Cn0+Cn1+……+Cnn-1+Cnn还不会啊!牛顿莱布尼兹公式记得吧!(可惜Word的公式编辑器安装不了)总共2的n次方案。有可能前面10天写了K个类,老板让你再加一种成分你就得再干10天,下一次再加一种你可得干20天哦!同时你可以发现你的类库急剧地膨胀!(老板可能会说你:XXX前K天你加了n个成分,怎么现在这么不上进呢?后K天只加了1个成分啊?!!可能你会拿个比给老板算算,老板那么忙会睬你吗?!有可能你的老板会说:不管怎么样我就要你加,K天你还给我加n个成分!!呵呵,怎么办啊!跳槽啊!跳槽了也没人要你!!人家一看就知道你没学设计模式)。下面我们就使用装饰器模式来设计这个库吧!下图是我们的设计图:

 

 

       下面是以上各个类的意义:

1.         Ingredient(成分):所有类的父类,包括它们共有的方法,一般为抽象类且方法都有默认的实现,也可以为接口。它有Bread和Decorator两个子类。这种实际不存在的,系统需要的抽象类仅仅表示一个概念,图中用红色表示。

2.         Bread(面包):就是我们三明治中必须的两片面包。它是系统中最基本的元素,也是被装饰的元素,和IO中的媒质流(原始流)一个意义。在装饰器模式中属于一类角色,所以其颜色为紫色。

3.         Decorator(装饰器):所有其它成分的父类,这些成分可以是猪肉、羊肉、青菜、芹菜。这也是一个实际不存在的类,仅仅表示一个概念,即具有装饰功能的所有对象的父类。图中用蓝色表示。

4.         Pork(猪肉):具体的一个成分,不过它作为装饰成分和面包搭配。

5.         Mutton(羊肉):同上。

6.         Celery(芹菜):同上。

7.         Greengrocery(青菜):同上。

总结一下装饰器模式中的四种角色:1.被装饰对象(Bread);2.装饰对象(四种);3.装饰器(Decorator);4.公共接口或抽象类(Ingredient)。其中1和2是系统或者实际存在的,3和4是实现装饰功能需要的抽象类。

       写段代码体会其威力吧!(程序很简单,但是实现的方法中可以假如如何你需要的方法,意境慢慢体会吧!)

         //Ingredient.java

public abstract class Ingredient {

         public abstract String getDescription();

         public abstract double getCost();    

         public void printDescription(){        

                   System.out.println(" Name      "+ this.getDescription());

                   System.out.println(" Price RMB "+ this.getCost());

         }

}

       所有成分的父类,抽象类有一个描述自己的方法和一个得到价格的方法,以及一个打印自身描述和价格的方法(该方法与上面两个方法构成模板方法哦!)

 

//Bread.java

public class Bread extends Ingredient {

         private String description ;

         public Bread(String desc){

                   this.description=desc ;

         }

         public String getDescription(){

                   return description ;

         }       

         public double getCost(){

                   return 2.48 ;

         }       

}

       面包类,因为它是一个具体的成分,因此实现父类的所有的抽象方法。描述可以通过构造器传入,也可以通过set方法传入。同样价格也是一样的,我就很简单地返回了。

 

//Decorator.java

public abstract class Decorator extends Ingredient {

     Ingredient ingredient ;

     public Decorator(Ingredient igd){

              this.ingredient = igd;     

     }       

     public abstract String getDescription();

     public abstract double getCost();

}

       装饰器对象,所有具体装饰器对象父类。它最经典的特征就是:1.必须有一个它自己的父类为自己的成员变量;2.必须继承公共父类。这是因为装饰器也是一种成分,只不过是那些具体具有装饰功能的成分的公共抽象罢了。在我们的例子中就是有一个Ingredient作为其成员变量。Decorator继承了Ingredient类。

 

//Pork.java

public class Pork extends Decorator{

         public Pork(Ingredient igd){

                   super(igd);

         }

         public String getDescription(){

                   String base = ingredient.getDescription();

                   return base +"/n"+"Decrocated with Pork !";

         }

         public double getCost(){

                   double basePrice = ingredient.getCost();

                   double porkPrice = 1.8;

                   return        basePrice + porkPrice ;

         }

}

       具体的猪肉成分,同时也是一个具体的装饰器,因此它继承了Decorator类。猪肉装饰器装饰可以所有的其他对象,因此通过构造器传入一个Ingredient的实例,程序中调用了父类的构造方法,主要父类实现了这样的逻辑关系。同样因为方法是具体的成分,所以getDescription得到了实现,不过由于它是具有装饰功能的成分,因此它的描述包含了被装饰成分的描述和自身的描述。价格也是一样的。价格放回的格式被装饰成分与猪肉成分的种价格哦!

       从上面两个方法中我们可以看出,猪肉装饰器的功能得到了增强,它不仅仅有自己的描述和价格,还包含被装饰成分的描述和价格。主要是因为被装饰成分是它的成员变量,因此可以任意调用它们的方法,同时可以增加自己的额外的共同,这样就增强了原来成分的功能。

      

//Mutton.java

public class Mutton extends Decorator{

         public Mutton(Ingredient igd){

                   super(igd);

         }

         public String getDescription(){

                   String base = ingredient.getDescription();

                   return base +"/n"+"Decrocated with Mutton !";

         }

         public double getCost(){

                   double basePrice = ingredient.getCost();

                   double muttonPrice = 2.3;

                   return        basePrice + muttonPrice ;

         }

}

       羊肉的包装器。

 

//Celery.java

public class Celery extends Decorator{

         public Celery(Ingredient igd){

                   super(igd);

         }

         public String getDescription(){

                   String base = ingredient.getDescription();

                   return base +"/n"+"Decrocated with Celery !";

         }

         public double getCost(){

                   double basePrice = ingredient.getCost();

                   double celeryPrice =0.6;

                   return        basePrice + celeryPrice ;

         }

}

       芹菜的包装器。

 

//GreenGrocery.java

public class GreenGrocery extends Decorator{

         public GreenGrocery (Ingredient igd){

                   super(igd);

         }

         public String getDescription(){

                   String base = ingredient.getDescription();

                   return base +"/n"+"Decrocated with GreenGrocery  !";

         }

         public double getCost(){

                   double basePrice = ingredient.getCost();

                   double greenGroceryPrice = 0.4;

                   return        basePrice + greenGroceryPrice ;

         }

}

       青菜的包装器。

      

       下面我们就领略装饰器模式的神奇了!我们有一个测试类,其中建立夹羊肉的三明治、全蔬菜的三明治、全荤的三明治。(感觉感觉吧!很香的哦!)

 

public class DecoratorTest{

         public static void main(String[] args){

                   Ingredient compound = new Mutton(new Celery(new Bread("Master24's Bread")));              

                   compound.printDescription();

                  

                   compound = new Celery(new GreenGrocery(new Bread("Bread with milk")));    

                   compound.printDescription();

                  

                   compound = new Mutton(new Pork(new Bread("Bread with cheese")));

                   compound.printDescription();

                  

         }

}

       以上就是一个简单的装饰器类!假如你对想中国式的吃法,可以将加入馒头、春卷皮、蛋皮……夹菜可以为肉丝……突然想到了京酱肉丝。

      

2 装饰器模式的结构

       在谈及软件中的结构,一般会用UML图表示(UML和ANT、JUnit等都是软件设计中基本的工具,会了没有啊!)。下面是一个我们经常看到的关于Decorator模式的结构图。

 

1.      Component就是装饰器模式中公共方法的类,在装饰器模式结构图的顶层。

2.      ConcreateComponent是转换器模式中具体的被装饰的类,IO包中的媒体流就是此种对象。

3.      Decorator装饰器模式中的核心对象,所有具体装饰器对象的父类,完成装饰器的部分职能。在上面的例子中Decorator类和这里的对应。该类可以只做一些简单的包裹被装饰的对象,也可以还包含对Component中方法的实现……他有一个鲜明的特点:继承至Component,同时包含一个Component作为其成员变量。装饰器模式动机中的动态地增加功能是在这里实现的。

4.      ConcreteDecoratorA和ConcreteDecoratorB是两个具体的装饰器对象,他们完成具体的装饰功能。装饰功能的实现是通过调用被装饰对象对应的方法,加上装饰对象自身的方法。这是装饰器模式动机中的添加额外功能的关键。

 

从上面图中你可能还会发现:ConcreteDecoratorA和ConcreteDecoratorB的方法不一样,这就是一般设计模式中谈及装饰器模式的“透明装饰器”和“不透明装饰器”。“透明装饰器”就是整个Decorator的结构中所有的类都保持同样的“接口”(这里是共同方法的意思),这是一种极其理想的状况,就像餐饮的例子一样。现实中绝大多数装饰器都是“不透明装饰器”,他们的“接口”在某些子类中得到增强,主要看这个类与顶层的抽象类或者接口是否有同样的公共方法。IO中的ByteArrayInputStream就比Inputstrem抽象类多一些方法,因此IO中的装饰器是一个“不通明装饰器”。下面是IO中输入字节流部分的装饰器的结构图。

 

1.         InputStream是装饰器的顶层类,一个抽象类!包括一些共有的方法,如:1.读方法――read(3个);2.关闭流的方法――close;3.mark相关的方法――mark、reset和markSupport;4.跳跃方法――skip;5.查询是否还有元素方法――available。图中红色的表示。

2.         FileInputStream、PipedInputStream…五个紫色的,是具体的被装饰对象。从他们的“接口”中可以看出他们一般都有额外的方法。

3.         FilterInputStream是装饰器中的核心,Decorator对象,图中蓝色的部分。

4.         DataInputStream、BufferedInputStream…四个是具体的装饰器,他们保持了和InputStream同样的接口。

5.         ObjectInputStream是IO字节输入流中特殊的装饰器,他不是FilterInputStream的子类(不知道Sun处于何种意图不作为FileterInputStream的子类,其中流中也有不少的例子)。他和其他FilterInputStream的子类功能相似都可以装饰其他对象。 

IO包中不仅输入字节流是采用装饰器模式、输出字节流、输入字符流和输出字符流都是采用装饰器模式。关于IO中装饰器模式的实现可以通过下面的源代码分析从而了解细节。

基于工作流的低代码AI应用开发:Flock平台核心架构与实战指南 在AI应用开发领域,工作流编排正成为连接大语言模型(LLM)能力与复杂业务逻辑的关键技术。其核心原理是将任务分解为模块化节点,通过可视化方式定义执行顺序与数据流向,从而实现灵活可控的自动化流程。这种范式极大地提升了开发效率,降低了技术门槛,使得开发者能够聚焦于业务设计而非底层代码。在技术价值层面,工作流编排支持检索增强生成(RAG)、多智能体协作等高级模式,并能通过人工干预节点确保关键流程的可靠性与合规性。其典型应用场景包括智能客服、自动化办公、数据分析助手等。本文以Flock平台为例,深入解析了如何利用其 阅读详情

相关推荐

Xilinx Vitis 2020.1头文件路径配置避坑指南:解决#include找不到文件的常见问题

本文针对Xilinx Vitis 2020.1开发环境中常见的#include头文件找不到问题,提供了系统的避坑指南。文章深入解析了Vitis的头文件搜索机制,对比了通过工程属性GUI、修改编译命令及使用环境变量三种配置方法的优劣与隐藏陷阱,并给出了高级场景的排查流程与工程结构最佳实践,帮助开发者高效解决路径配置难题。

weixin_28831399的博客 573

一次性全方位解读 Java IO (装饰器模式篇)

装饰器模式主要用于解决继承关系复杂的问题,通过组合和委托来替代继承。装饰器模式的主要作用就是给组件添加增强功能,可以在组件功能代码的前面、后面添加自己的功能代码,甚至可以将组件的功能代码完全替换掉。装饰器和具体的组件都继承相同的抽象类或接口(组件),所以可以使用无数个装饰器包装一个具体的组件。装饰器模式也是有问题的,它会导致设计中出现许多小类,如果过度使用,会让程序变得很复杂。

wdj_yyds的博客 1140

从压电传感器到示波器:手把手教你用CA3140搭建电荷放大器(含PCB布局与调零技巧)

本文详细介绍了如何使用CA3140运算放大器搭建专业级电荷放大器,从压电传感器信号特性分析到PCB布局与调零技巧,全程实战演示。重点解析了CA3140的低通滤波器设计、反馈网络参数计算及抗干扰增强方案,帮助电子爱好者高效实现微弱电荷信号的稳定转换与测量。

weixin_31355483的博客 600

Java IO 设计模式总结

装饰器模式(Decorator)可以在不改变原有对象的情况下拓展其功能。装饰器模式通过组合替代继承来扩展原始类的功能,在一些继承关系比较复杂的场景(IO这一场景各种类的继承关系就比较复杂)更加实用。

Zero摄氏度的博客 2020

MTK Sensor驱动调试实战:从AP到SCP的完整流程解析

本文详细解析了MTK平台Sensor驱动从AP侧到SCP侧的完整调试流程。内容涵盖AP侧驱动集成、DTS配置、内核编译与验证,以及SCP侧Tinysys框架下的代码集成、Overlay配置与I2C设置等核心步骤,并分享了中断唤醒、功耗优化及传感器数据校准等实战经验与常见问题排查方法,为硬件驱动工程师提供了一份全面的实战指南。

weixin_29175469的博客 354

动态库加载失败终极指南:从libbz2.so.1错误看Linux依赖管理本质

本文以经典的libbz2.so.1加载错误为例,深入剖析Linux动态链接库管理的核心机制。文章不仅提供从ldd检查、符号链接创建到LD_LIBRARY_PATH设置等实战解决方案,更系统性地讲解了动态链接器的寻库路径、版本管理及依赖问题预防策略,帮助开发者从根本上理解和掌握Linux依赖管理本质。

weixin_29212429的博客 449

4.java的IO流技术(2/2)

java的IO流技术

ZXG20000的博客 288

【华为OD技术面试真题 - 技术面】- C++面试题(1)

2024华为OD面试手撕代码真题目录以及八股文真题目录

算法大师! 3398

来,我们一起搞懂Java 3种IO模型!

外观模式(Facade Pattern)是一种结构型设计模式,它通过提供一个统一的接口,简化了接口的复杂性,使得客户端能够更加方便地访问系统的子系统。它将多个复杂的子系统进行封装,对外提供一个简化的接口,使得客户端可以更加方便地使用系统。外观模式是一种结构型设计模式,它为复杂系统提供了一个简单的接口。它隐藏了系统的复杂性,提供了一个统一的接口,使得客户端可以更容易地使用系统。外观模式在许多大型系统中很常见,因为它可以简化系统的使用并提高可维护性。

BASK2311的博客 764

【系统架构设计师-2026上半年真题】综合知识-参考答案及详解(75题完全回忆版)

【系统架构设计师-2026上半年真题】综合知识-参考答案及详解(75题完全回忆版)

数据知道的博客 3116

AUTOSAR从入门到精通-汽车电子电气架构(EEA)(二)

需求的传递并非完全是瀑布式的单向传递,而是双向的,只有被下游接受了的需求才是有效的需求,而且,下游是可以反向对上游提出需求的。当街区的设计完成之后,接下来要做的就是每栋建筑的详细设计,建筑的设计者发布的图纸中规定了房屋的主要结构、所在位置与周边环境的相互关系,以及屋中各种组件的位置与相互之间结合的关系,比如砖混结构、房屋的具体位置和朝向、卧室与客厅的相对位置与尺寸、马桶在卫生间中的位置等,还会对各种建筑材料的选取原则给出具体的标准,比如水泥的标号,钢筋的型号,各种电线的等级要求等等。

getusushu的博客 373

Java IO | 装饰器模式 | 扩展和定制流功能

Java中的装饰器类位于java.io包中。这些类实现了装饰器模式,允许我们在IO流中添加额外的功能。

devops 4052

CATIA二次开发核心技术:多实体零件自动化拆解与装配生成深度解析(零件转产品)

CATIA二次开发核心技术:多实体零件自动化拆解与装配生成深度解析

KE17RS的博客 2146

装饰器模式 Decorator(摘要 转载)

1.意图: 在一个对象的外围创建一个称为装饰器的封装,动态地给这个对象添加一些额外的功能。 2.类图: 3.原理: 在一个对象的外围创建一个称为装饰器的封装,动态地给这个对象添加一些额外的功能。以对客户端透明的方式扩展对象的功能。 装饰器模式又称为包裹模式(wrapper),因为一个具体装饰器都将下一个具体装饰器或具体构件类包裹起来...

Javy的专栏 138

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

装饰器模式(Decorator)——深入理解与实战应用

本文转载自:https://www.cnblogs.com/jzb-blog/p/6717349.html,感谢博主,转载以作笔记。 1、初识装饰器模式 2、最简单的代码实现装饰器模式 //基础接口 public interface Component { public void biu(); } //具体实现类 public class ConcretCompone...

南有乔木的博客 1万+

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

装饰器模式(Decorator Pattern)

装饰器模式(Decorator Pattern) 标签: 设计模式   装饰器模式是一种结构型模式,目标是动态的给一个对象添加一些额外的职责,装饰器模式使用组合而不是继承的方式来实现。   核心代码是包装器的构造方法传入组件作为参数,再把构造出来的类传入其他包装器,实现不断包装、不同组合包装的过程。   UML类结构图: Component :用来规范被装饰的对象的接口。 Concr...

diaoyang7352的博客 124

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

The Decorator 装饰器模式(JAVA)

--只是记录学习的点滴,错误请指出``` 装饰器模式能解决什么问题 1: Responsibilities should be added to (and removed from) an object dynamically at run-time. 2:A flexib...

chuangtunzi31247的博客 162

Decorator(装饰器模式)

装饰器模式允许我们根据运行时不同的情景动态地为某个对象调用前后添加不同的行为动作。 <?php class HtmlTemplate { // any parent class methods } class Template1 extends HtmlTemplate { protected $_html; pub...

91

装饰器模式(Decorator)

转载http://blog.youkuaiyun.com/hust_is_lcd/article/details/7884320 [-] 认识装饰器模式 装饰模式能够实现动态的为对象添加功能,是从一个对象外部来给对象添加功能。通常给对象添加功能,要么直接修改对象添加相应的功能,要么派生对应的子类来扩展,抑或是使用对象组合的方式。显然,直接修改对应的类这种方式并不可取。在面向对...

weixin_30518397的博客 74

设计模式(八)装饰器模式Decorator(结构型)

设计模式(八)装饰器模式Decorator(结构型)

skiwnc的博客 278

php装饰器模式(decorator pattern)

十一点了。 <?php /* The decorator pattern allows behavior to be added to an individual object instance, without affecting the behavior of other instances of the same class. We can define multiple...

weixin_30500473的博客 103

转载Java设计模式之装饰Decorator模式

原文地址:https://blog.youkuaiyun.com/zaoan_2010/article/details/83308891 简单介绍装饰器模式 装饰模式,动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。(引自《大话设计模式》) 装饰器模式的结构图如下: Component:对象接口,也可以是一个抽象类,是被装饰类和装饰类的基本类型,可以给这些对象动态地...

meihao1203dick的博客 159

Decorator模式 装饰器模式

Android 使用了装饰器模式 1. 概述 若你从事过面向对象开发,实现给一个类或对象增加行为,使用继承机制,这是所有面向对象语言的一个基本特性。如果已经存在的一个类缺少某些方法,或者须要给方法添加更多的功能(魅力),你也许会仅仅继承这个类来产生一个新类—这建立在额外的代码上。 通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法...

weixin_30301449的博客 63

js 装饰器_JavaScript中的注解之装饰器模式

1 什么是装饰器模式?装饰器模式模式动态地扩展了(装饰)一个对象的行为,同时又不改变其结构。在运行时添加新的行为的能力是由一个装饰器对象来完成的,它 "包裹 "了原始对象,用来提供额外的功能。多个装饰器可以添加或覆盖原始对象的功能。装饰器模式属于结构型模式。和适配器模式不同的是,适配器模式是原有的对象不能用了,而装饰器模式是原来的对象还能用,在不改变原有对象结构和功能的前提下,为对象添加新功能。装...

weixin_39925813的博客 179
上一篇: General Introduction of Web Service Security
下一篇: A Survey of Web 2.0 Technologies
TopestCoder
博客等级 码龄19年 12粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值