用途


装饰者模式 (Decorator)
动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator 模式相比生成子类更为灵活。

装饰者模式是一种结构式模式
结构


图-装饰者模式结构图
Component : 定义一个对象接口,可以给这些对象动态地添加职责。
interface Component {
    public void operation();
}
ConcreteComponent : 实现 Component 定义的接口。
class ConcreteComponent implements Component {
    @Override
    public void operation() {
        System.out.println("初始行为");
    }
}
Decorator : 装饰抽象类,继承了 Component, 从外类来扩展 Component 类的功能,但对于 Component 来说,是无需知道 Decorator 的存在的。
class Decorator implements Component {
    // 持有一个 Component 对象,和 Component 形成聚合关系
    protected Component component;
    
    // 传入要进一步修饰的对象
    public Decorator(Component component) {
        this.component = component;
    }
    
    @Override
    // 调用要修饰对象的原方法
    public void operation() {
        component.operation();
    }
}
ConcreteDecorator : 具体的装饰对象,起到给 Component 添加职责的功能。
class ConcreteDecoratorA extends Decorator {
    private String addedState = "新属性1";
    
    public ConcreteDecoratorA(Component component) {
        super(component);
    }
    
    public void operation() {
        super.operation();
        System.out.println("添加属性: " + addedState);
    }
}

class ConcreteDecoratorB extends Decorator {
    public ConcreteDecoratorB(Component component) {
        super(component);
    }

public void operation() {
        super.operation();
        AddedBehavior();
    }
    
    public void AddedBehavior() {
        System.out.println("添加行为");
    }
}

测试代码

public class DecoratorPattern {
    public static void main(String[] args) {
        Component component = new ConcreteComponent();
        component.operation();
        
        System.out.println("======================================");
        Decorator decoratorA = new ConcreteDecoratorA(component);
        decoratorA.operation();
        
        System.out.println("======================================");
        Decorator decoratorB = new ConcreteDecoratorB(decoratorA);
        decoratorB.operation();
    }
}

运行结果

初始行为
======================================
初始行为
添加属性: 新属性1
======================================
初始行为
添加属性: 新属性1
添加行为
应用场景


1、需要动态的、透明的为一个对象添加职责,即不影响其他对象。

2、需要动态的给一个对象添加功能,这些功能可以再动态的撤销。

3、需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。

4、当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

要点


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

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

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

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

推荐

本文属于 JAVA设计模式系列

参考资料

《大话设计模式》

《HeadFirst设计模式》

JAVA 设计模式 装饰者模式相关推荐

  1. Java设计模式——装饰者模式

    概述 本章可以称为"给爱用继承的人一个全新的设计眼界".我们即将再度探讨典型滥用问题.你将在本章学到如何使用对象组合的方式,做到在运行时装饰类.为什么呢?一旦你熟悉了装饰者的技巧, ...

  2. Java设计模式-装饰器模式 理论代码相结合

    继Java设计模式适配器模式后的装饰器模式来啦,让我们一起看看吧. 会了就当复习丫,不会来一起来看看吧. 很喜欢一句话:"八小时内谋生活,八小时外谋发展". 如果你也喜欢,让我们一 ...

  3. java设计模式装饰者模式优点_java设计模式之--装饰者模式

    装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包装 ...

  4. java设计模式----装饰器模式

    Decorator装饰器,顾名思义,就是动态地给一个对象添加一些额外的职责,就好比为房子进行装修一样.因此,装饰器模式具有如下的特征: 它必须具有一个装饰的对象. 它必须拥有与被装饰对象相同的接口. ...

  5. java设计模式---装饰器模式

    装饰者模式 动态地将责任附加到对象上.若要扩展功能,装饰者提供了比继承更有弹性的替代方案. 具体被装饰者和抽象装饰类都继承于抽象被装饰者类,继承的是类型,而不是行为.行为来自装饰者和基础组件,或与其他 ...

  6. java装饰者模式服装搭配,学习、探究Java设计模式——装饰者模式

    定义 装饰者模式:在不改变原类文件以及不使用继承的情况下,动态地将责任附加到对象上,从而实现动态拓展一个对象的功能.它是通过创建一个包装对象,也就是装饰来包裹真实的对象. 设计原则 要使用装饰者模式, ...

  7. Java设计模式----------装饰器模式

    1.介绍 装饰器模式是一种结构型的设计模式.使用该模式的目的是为了较为灵活的对类进行扩展,而且不影响原来类的结构.有同学说可以通过继承的方式进行实现啊,没错,继承的确可以实现,但是继承的成本相对比较高 ...

  8. Java设计模式-装饰者模式

    1 概述 我们先来看一个快餐店的例子. 快餐店有炒面.炒饭这些快餐,可以额外附加鸡蛋.火腿.培根这些配菜,当然加配菜需要额外加钱,每个配菜的价钱通常不太一样,那么计算总价就会显得比较麻烦. 使用继承的 ...

  9. JAVA设计模式-装饰器模式(Decorator)

    装饰器模式(Decorator) 为了某个实现类在不修改原始类的基础上进行动态地覆盖或者增加方法 采用--------装饰器模式 实现类要保持与原有类的层级关系 装饰器模式是一种特殊的适配器模式 拿适 ...

  10. Java设计模式--装饰者模式【Decorator Pattern】

    有时,你想要在程序运行期间为某个对象组合新的行为,且在某种情况下,你需要对象的行为发生一些细小的变化,并且这些变化可以自由组合.这时,装饰者模式就可以满足这种需求. 所谓装饰者模式,也叫修饰者模式.装 ...

最新文章

  1. 去除浮动列表的右边距 利用负边距
  2. sql-server基础知识四(视图和索引)
  3. Python基础教程:判断列表重复
  4. 新认知,新力量!神策 2021 数据驱动大会来了
  5. foreach循环怎么获取全部返回值_JavaScript中For循环的3种版本和使用场景
  6. canvas.translate(x,y)
  7. 解决npm 的 shasum check failed for错误
  8. c语言第八章实验题答案,第八章实验报告
  9. pyjion python3.6_[新闻] CPython / 微软 Pyjion / IBM Python+OMR
  10. c++ 创建txt,写log
  11. 复制百度文库的文字加什么后缀_如何复制百度文中的文章.doc
  12. # 研究杂感 × VOSviewer(第一辑)
  13. oracle中如何模糊匹配,oracle中的截取,模糊匹配小结
  14. imx6 linux内核定义debug口,IMX6Q 调试串口修改
  15. linux下批量修改文件名称
  16. 开关稳压集成电路电源
  17. 智能系统概论——初识百度AI平台
  18. macbook配置java环境变量_Mac怎么配置JDK环境变量 安装JDK并配置环境变量教程
  19. Linux 虚拟机VMware安装失败,提示没有选择磁盘no disks selected
  20. 分数换算小数补0法_小学数学常用公式大全(单位换算表) 长度单位换算【建议收藏】...

热门文章

  1. 雷林鹏分享:PHP 实例 - AJAX 与 XML
  2. Elasticsearch增删改查 之 —— mget多文档查询
  3. Centos 6.3下使用源码安装Mysql 5.5
  4. HTML5 Guitar Tab Player
  5. centos7 安装mysql_第02期:ClickHouse 单机部署以及从 MySQL 增量同步数据
  6. nginx实战(五) 正向代理支持https
  7. 以太坊执行miner.start返回null终极解决方案
  8. 编程开发之--java多线程学习总结(4)
  9. sharepoint 2007 无法自动跳转到default.aspx
  10. PhotoShop如何给字体添加下划线