JAVA 设计模式 装饰者模式

用途

装饰者模式 (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设计模式》

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大闲人柴毛毛

Java并发编程的艺术(二)——重排序

当我们写一个单线程程序时,总以为计算机会一行行地运行代码,然而事实并非如此。 什么是重排序? 重排序指的是编译器、处理器在不改变程序执行结果的前提下,重新排列指...

35910
来自专栏chenssy

【死磕Java并发】-----Java内存模型之重排序

在执行程序时,为了提供性能,处理器和编译器常常会对指令进行重排序,但是不能随意重排序,不是你想怎么排序就怎么排序,它需要满足以下两个条件: 1. 在单线程环境...

1132
来自专栏Android常用基础

粗谈Java虚拟机之内存管理

线程私有,生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息...

682
来自专栏Java学习网

Java中的内存泄漏学习

Java中的内存泄漏学习   Java语言的一个关键的优势就是它的内存管理机制。你只管创建对象,Java的垃圾回收器帮你分配以及回收内存。然而,实际的情况并没...

2108
来自专栏林德熙的博客

dotnet 设计规范 · 抽象类

X 不要定义 public 或 protected internal 访问的构造函数。默认 C# 语言不提供抽象类的公开构造函数方法。

552
来自专栏虚拟化云计算

OpenStack数据库远程对象模型

在OpenStack的各个服务之间有些数据库对象是远程操作的,远程对象所实现的效果是:一个 A 服务中的远程对象实例,可以由消息队列传送到B 服务,B 服务能够...

712
来自专栏向治洪

数据结构之堆和栈

内存分配策略     按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的.  静态存储分配是指在编译时就能确定每个数据目标...

1869
来自专栏各种机器学习基础算法

php链式操作的实现

一、什么是链式操作? 直接说链式操作,也许大家不清楚是什么,但是在平时使用框架的过程中,大家肯定见到过这样子的使用: $db->where()->limit()...

3277
来自专栏张善友的专栏

读《代码不朽:编写可维护软件的10大要则》C# 版

这本书特别针对没有接受过计算机科学或软件工程专业学习的软件开发人员,这类人员除了熟悉所用语言语法和语义之外,很少接受其他专业培训,对软件工程中的一些概念理解欠缺...

5840
来自专栏阿杜的世界

如何设计接口的测试用例边界值测试组合条件测试

今天在帮同事review代码的时候,发现他的代码遗漏了一些场景的处理,就顺便跟他多聊了些为对这个话题的看法。

592

扫码关注云+社区