12 装饰模式

12.1 装饰模式概述

Decorator Pattern: 动态地给一个对象增加一些额外的职责。提供一种比使用子类更加灵活的方案来扩展功能。

装饰模式是一种用于替代继承的技术,通过一种无须定义子类的方式给对象动态增加职责,使用对象之间的关联关系替代类之间继承关系。

装饰模式结构图如下所示:

12.2 装饰模式实现

12.2.1 抽象构件类

它是具体构件类和抽象装饰类的共同父类,它的引入使得客户端可以以一致的方式处理未装饰的对象和已装饰的对象,实现客户端的透明操作。

public abstract class Component {
public abstract void operation();
}

12.2.2 具体构件类

实现抽象构件中声明的方法,装饰类可以给它增加额外的方法。

public class ConcreteComponent extends Component {
public void operation() {
// 业务代码
}
}

12.2.3 抽象装饰类

用于给具体构件类增加职责,但是具体增加的职责在其子类中实现。

public class Decorator extends Component {
private Component component; public Decorator(Component component) {
this.component = component;
} public void operation() {
// 调用原有业务方法
component.operation();
}
}

12.2.4 具体装饰类

负责向具体构件中添加新的职责。

public class ConcreteDecorator extends Decorator {
public concreteDecorator(Component component) {
super(component);
} public void operation() {
super.operation(); // 新增的职责
addMethod();
} public void addMethod() {
// 新增职责逻辑
}
}

12.2.5 客户端调用

public class Client {
public static void main(String[] args) {
Component component, decorator;
component = new ConcreteComponent();
decorator = new ConcreteDecorator(component); // 一致的方式处理未装饰的对象和已装饰的对象
componet.operation();
decorator.operation();
}
}

12.3 透明装饰模式与半透明装饰模式

12.3.1 透明装饰模式

上述装饰模式的实现即为透明装饰模式,要求客户端完全针对抽象编程。装饰模式的透明性要求客户端程序将对象声明为抽象构件类型,可以一致的处理装饰对象和未装饰对象。

但是在某些情况下,有些新增行为需要单独被调用,此时如果使用透明装饰模式,则无法一致的处理装饰前的对象和装饰后的对象(装饰后的对象需要强制类型转换调用新增行为)。

12.3.2 半透明装饰模式

为了能够调用到新增的方法,不得不用具体装饰类型来定义装饰之后的对象,而具体构件对象可以使用抽象构件声明,这种装饰模式则称为半透明

public class Client {
Component component;
component = new ConcreteComponent();
component.operation(); ConcreteDecorator decorator = new ConcreteDecorator(component);
decorator.operation();
decorator.addMethod();
}

半透明模式可以给系统带来更多的灵活性,使用起来也非常方便;但是其缺点是客户端需要区别的对象装饰对象和未装饰对象。

12.4 装饰模式优/缺点

使用场景:Java I/O 输入流和输出流

装饰模式的优点主要如下:

  • 对于扩展一个类的功能,装饰模式比继承更加灵活
  • 可以对一个对象进行多次装饰,通过使用不同的装饰类得到功能更强大的对象
  • 具体构件类和具体装饰类可以独立变化,用户根据需要增加新的构件类和装饰类,无须修改原有代码,符合开闭原则

装饰模式的缺点主要如下:

  • 装饰模式提供了一种比继承更灵活的方式,同时也比继承更加易于出错,排错也更加困难,对于多次装饰的对象

Java设计模式 —— 装饰模式的更多相关文章

  1. Java设计模式---装饰模式

    装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰模式的结构 装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任.换言之,客户 ...

  2. Java设计模式-装饰模式(Decorator)

    顾名思义,装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例,关系图如下: Source类是被装饰类,Decorator类是一个 ...

  3. Java设计模式—装饰模式

    装饰模式是一种比较常见的模式. 定义为:动态的给一个对象添加一些额外的职责.就增加功能来说,装饰模式比生成子类更加灵活. 装饰模式的通用类图如下: 装饰模式的构成: 1) 抽象构件(Component ...

  4. Java设计模式——装饰模式

    转载自:http://blog.csdn.net/xu__cg/article/details/53024490 抽象构件 public interface CarInterface { void m ...

  5. Java设计模式学习记录-装饰模式

    前言 装饰模式也是一种结构型模式,主要是目的是相对于类与类之间的继承关系来说,使用装饰模式可以降低耦合度.JDK中有不少地方都使用到了装饰模式,例如Java的各种I/O流,javax.swing包中一 ...

  6. Java设计模式(7)装饰模式(Decorator模式)

    Decorator常被翻译成"装饰",我觉得翻译成"油漆工"更形象点,油漆工(decorator)是用来刷油漆的,那么被刷油漆的对象我们称decoratee.这 ...

  7. Java设计模式(三) 抽象工厂模式

    原创文章,同步发自作者个人博客,转载请注明出处 http://www.jasongj.com/design_pattern/abstract_factory/ 抽象工厂模式解决的问题 上文<工厂 ...

  8. Java设计模式(十二) 策略模式

    原创文章,同步发自作者个人博客,http://www.jasongj.com/design_pattern/strategy/ 策略模式介绍 策略模式定义 策略模式(Strategy Pattern) ...

  9. Java设计模式(二) 工厂方法模式

    本文介绍了工厂方法模式的概念,优缺点,实现方式,UML类图,并介绍了工厂方法(未)遵循的OOP原则 原创文章.同步自作者个人博客 http://www.jasongj.com/design_patte ...

  10. Java设计模式(一) 简单工厂模式不简单

    摘要:本文介绍了简单工厂模式的概念,优缺点,实现方式,以及结合Annotation和反射的改良方案(让简单工厂模式不简单).同时介绍了简单工厂模式(未)遵循的OOP原则.最后给出了简单工厂模式在JDB ...

随机推荐

  1. mybatis核心配置文件

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC ...

  2. redis远程连接错误SocketTimeoutException: connect timed out

    redis远程连接错误SocketTimeoutException: connect timed out 解决方案: 编辑redis.conf文件(建议将其 先备份 编辑备份文件 启动redis服务时 ...

  3. Linux系列---【yum安装已下载好的rpm包】

    yum安装已下载好的rpm包 先进入已下载好的rpm包的目录,然后执行下面的命令 yum localinstall xxx.rpm

  4. Linux系统环境下部署jar程序实现后台运行1

    [ nohup java -jar xxx.jar --spring.profiles.active=prod > 日志文件名 2>&1 & ]

  5. WCF使用post 提交

    [OperationContract] [WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFor ...

  6. python高阶编程(一)

    1.生成器 通过列表⽣成式,我们可以直接创建⼀个列表.但是,受到内存限制,列表容量肯定是有限的.⽽且,创建⼀个包 含100万个元素的列表,不仅占⽤很⼤的存储空间,如果我们仅仅需要访问前⾯⼏个元素,那后 ...

  7. 深入理解C++的型别推导

    所谓型别推导,指的是我们在为变量赋予类型时不必再显式声明,编译器可以根据代码来自动推导类型.C++11中有两种型别推导的场景:模板和auto.下面我们来一一解析. 模板的型别推导 模板在C++中的应用 ...

  8. Mysql 5.7 内存配置 (未完成)

    innodb_buffer_pool_size = 4024024024 innodb 引擎,用于 缓存数据和索引

  9. 博弈论练习6 Deleting Divisors(sg找规律,思维)

    题目链接在这里:G-Deleting Divisors_牛客竞赛博弈专题班组合游戏基本概念.对抗搜索.Bash游戏.Nim游戏习题 (nowcoder.com) 这道题一道比较明显的思路是使用sg函数 ...

  10. 6Sampling Configuration Space: 6.3 Using Accelerated Molecular Dynamics (aMD) to enhance sampling

    6.3 Using Accelerated Molecular Dynamics (aMD) to enhance sampling 英文官网:http://ambermd.org/tutorials ...