Java设计模式之(七)——装饰器模式
1、什么是装饰器模式?
Attach additional responsibilities to an object dynamically keeping the same interface.Decorators provide a flexible
alternative to subclassing for extending functionality.
装饰器模式(Decorator Pattern):动态的给一个对象添加额外的职责,就增加功能来说, 装饰模式相比生成子类更为灵活。
说人话:一般的,我们为了扩展一个类经常使用继承方式实现,随着扩展功能的增多,子类会很膨胀。这时候期望在不改变类对象及其类定义的情况下,为对象添加额外功能,这就是装饰器模式。
2、装饰器模式定义

①、Component抽象构件
Component是一个接口或者是抽象类, 就是定义我们最核心的对象, 也就是最原始的对象。
②、ConcreteComponent 具体构件
ConcreteComponent是最核心、 最原始、 最基本的接口或抽象类的实现, 你要装饰的就是它。
③、Decorator装饰角色
一般是一个抽象类, 实现接口或者抽象方法, 它里面可不一定有抽象的方法, 在它的属性里必然有一个private变量指向Component抽象构件。
④、ConcreteDecorator 具体装饰角色
ConcreteDecoratorA和ConcreteDecoratorB是两个具体的装饰类, 你要把你最核心的、 最原始的、 最基本的东西装饰成其他东西
3、装饰器模式通用代码实现
/**
* 抽象构件
*/
public abstract class Component {
public abstract void operator();
}
/**
* 具体构件
*/
public class ConcreteComponent extends Component{
@Override
public void operator() {
System.out.println("doSomething");
}
}
/**
* 抽象装饰者
*/
public abstract class Decorator extends Component{
private Component component;
public Decorator(Component component){
this.component = component;
}
// 委托给被修饰者执行
@Override
public void operator() {
this.component.operator();
}
}
public class ConcreteDecorator1 extends Decorator{
// 定义被修饰者
public ConcreteDecorator1(Component component){
super(component);
}
// 定义自己的修饰方法
public void method1(){
System.out.println("修饰方法 method1");
}
@Override
public void operator() {
this.method1();
super.operator();
}
}
public class ConcreteDecorator2 extends Decorator{
// 定义被修饰者
public ConcreteDecorator2(Component component){
super(component);
}
// 定义自己的修饰方法
public void method2(){
System.out.println("修饰方法 method2");
}
@Override
public void operator() {
super.operator();
this.method2();
}
}
客户端测试:
public class DecoratorClient {
public static void main(String[] args) {
Component component = new ConcreteComponent();
// 第一次修饰
component = new ConcreteDecorator1(component);
// 第二次修饰
component = new ConcreteDecorator2(component);
// 修饰后运行
component.operator();
}
}
打印结果:

4、装饰器模式优点
①、装饰模式可以动态地扩展一个实现类的功能。
②、装饰类和被装饰类可以独立发展, 而不会相互耦合。 换句话说, Component类无须知道Decorator类, Decorator类是从外部来扩展Component类的功能, 而Decorator也不用知道具体的构件。
③、装饰模式是继承关系的一个替代方案。 我们看装饰类Decorator, 不管装饰多少层, 返回的对象还是Component, 实现的还是is-a的关系
5、装饰器模式应用场景
①、需要扩展一个类的功能, 或给一个类增加附加功能。
②、需要动态地给一个对象增加功能, 这些功能可以再动态地撤销。
Java设计模式之(七)——装饰器模式的更多相关文章
- 重学 Java 设计模式:实战装饰器模式(SSO单点登录功能扩展,增加拦截用户访问方法范围场景)
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 对于代码你有编程感觉吗 很多人写代码往往是没有编程感觉的,也就是除了可以把功能按照固 ...
- Java设计模式12:装饰器模式
装饰器模式 装饰器模式又称为包装(Wrapper)模式.装饰器模式以多客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰器模式的结构 通常给对象添加功能,要么直接修改对象添加相应的功能, ...
- JAVA设计模式之【装饰者模式】
JAVA设计模式之[装饰者模式] 装饰模式 对新房进行装修并没有改变房屋的本质,但它可以让房子变得更漂亮.更温馨.更实用. 在软件设计中,对已有对象(新房)的功能进行扩展(装修). 把通用功能封装在装 ...
- Java IO流以及装饰器模式在其上的运用
流概述 Java中,流是一种有序的字节序列,可以有任意的长度.从应用流向目的地称为输出流,从目的地流向应用称为输入流. Java的流族谱 Java的 java.io 包中囊括了整个流的家族,输出流和输 ...
- 设计模式学习心得<装饰器模式 Decorator>
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包装 ...
- 设计模式入门之装饰器模式Decorator
//装饰模式定义:动态地给一个对象加入一些额外的职责. //就添加功能来说.装饰模式比生成子类更为灵活 //这也提现了面向对象设计中的一条基本原则,即:尽量使用对象组合,而不是对象继承 //Compo ...
- java进阶系列之装饰器模式
1.介绍 装饰器模式顾名思义就是装饰某个对象的,是一种结构型模式.装饰器模式允许向一个现有对象添加新的功能,同时不改变其结构,用户可以随意的扩展原有的对象.它是作为现有的类的一个包装.装饰器模式一方面 ...
- 设计模式のDecoratorPattern(装饰器模式)----结构模式
一.产生背景 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装 ...
- JAVA设计模式初探之装饰者模式
定义:动态给一个对象添加一些额外的职责,就象在墙上刷油漆.使用Decorator模式相比用生成子类方式达到功能的扩充显得更为灵活.设计初衷:通常可以使用继承来实现功能的拓展,如果这些需要拓展的功能的种 ...
- java设计模式-观察者模式,装饰者模式
1.1定义 慨念:定义了对象之间的一对多的依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新. 即:主题和观察者定义了一对多的关系,观察者依赖于主题,只要主题发生变化,观察者就 ...
随机推荐
- Task 异步小技巧
原文地址:Task 异步小技巧 - 一事冇诚 - 博客园 (cnblogs.com) async Task 语法糖出来后,异步编程变得非常简单,适合需要耗费较长时间的任务. 有些小伙伴使用后可能会非常 ...
- GoLang设计模式10 - 中介者模式
中介者模式是一种行为型设计模式.在中介者模式中创建了一个中介对象来负责不同类间的通信.因为这些类不需要直接交互,所以也就能避免它们之间的直接依赖,实现解耦的效果. 中介者模式的一个典型案例是老式小火车 ...
- 初识Tomcat源码
Tomcat 部署的三种方式 打包成war包 部署到webapp目录录下 为什么要打包成war包,而不是jar包呢? 因为jar包可能是一个项目,也可能是一个依赖,Tomcat读取容易造成混淆.于是一 ...
- python中dump与dumps实现序列化
前言 使用中如果我们想把python可识别对象的dict类型的数据通过str类型写入文件或者存入变量中就需要用到dump与dumps 详解 dump 1.新建个dict文件,然后将dict文件存入一个 ...
- repartition导致的广播失败,关于错误Failed to get broadcast_544_piece0 of broadcast_544
今天一个生产环境任务出现了性能问题,,经过仔细检查发现是在一个join操作时,原设定广播右表数据广播失败,导致后续步骤进行缓慢,,报错信息 java.io.IOException: org.apach ...
- sql递归查询部门数据
1 with cte as 2 ( 3 select a.DepartCode,a.DepartName,a.ParentDepartCode from tbDeparts a where Paren ...
- 腾讯bugly产生bug定位行数不准解决方案
定位不准是因为做了混淆导致行数与实际代码行数不对.解决方案是要上传符号表.下载地址https://bugly.qq.com/v2/downloads 下载好因为我打开文件的说明文件是空文件(可能工作人 ...
- 占位符,SQL注入?
这两天在上课时被同学拿了一段代码问我,这段代码有什么问题,我看了一会说:Connection和PreparedStatement都没关.他说不止这方面的问题,还有sql注入的问题,我就坚决的说使用了占 ...
- AIApe问答机器人Scrum Meeting 5.3
Scrum Meeting 6 日期:2021年5月3日 会议主要内容概述:汇报两日工作. 一.进度情况 组员 负责 两日内已完成的工作 后两日计划完成的工作 工作中遇到的困难 李明昕 后端 与前端对 ...
- C/C++中浮点数输出精度的问题
本文使用C++语言书写,对于C的小伙伴们,如果编译不通过的话--就说明C里面没有这个内容,可以跳过 通常来说,我们书写程序主要只用整形变量 (signed/unsigned) (long/long l ...