一、定义

装饰模式的设计理念主要是以对客户端透明的方式动态扩展对象的功能,是继承关系的一个替代(继承会产生大量的子类,而且代码有冗余)。装饰模式可以在不创造更多子类的情况下,将对象的功能加以扩展。装饰模式把客户端的调用委派到被装饰类。装饰模式的关键在于这种扩展完全是透明的(装饰模式的透明性要求客户端程序不应该将对象声明为具体构件类型或具体装饰类型,而应该全部声明为抽象构件类型),装饰模式的应用在java的I/O流中最为显著。

二、角色

  • 抽象构件角色(Component):通常是一个抽象类或者一个接口,定义了一系列方法,方法的实现可以由子类实现或者自己实现。通常不会直接使用该类,而是通过继承该类或者实现该接口来实现特定的功能。(例如,对于动物类,有一个抽象方法输出所有的功能,基本功能包括:呼吸,觅食,睡觉等等)
  • 具体构件角色(Concrete Component):是Component的子类,实现了对应的方法,它就是那个被装饰的类。(具体构建角色可以建立很多个,例如狗,猫,鸟等等,如果是狗,我们可以装饰一些吼叫的功能,吃肉的功能;鸟可以装饰一些飞行的功能,带有翅膀的功能等等。当然这些需要在具体装饰角色中去具体定义)
  • 装饰角色(Decorator):是Component的子类,它是具体装饰角色共同实现的抽象类(也可以是接口),并且持有一个Component类型的对象引用,它的主要作用就是把客户端的调用委派到被装饰类。
  • 具体装饰角色(Concrete Decorator):它是具体的装饰类,是Decorator的子类,当然也是Component的子类。它主要就是定义具体的装饰功能,例如上面说的,对于鸟这个具体构建角色而言,除了具备抽象构件角色基本的功能,它还具有一些飞行的功能,带翅膀的功能。那么我们可以把这两个功能定义成一个具体装饰角色1,对于狗这个具体构件角色而言,我们可以把吼叫,吃肉这两个功能定义成一个具体装饰角色2,这样,如果我们再定义一个狼这样的具体构件角色的时候,就可以直接用具体装饰角色2来进行装饰。

图片来源于(https://blog.csdn.net/nugongahou110/article/details/50413668)

三、Example

以上面所说的动物的例子来写代码演示。

抽象构件角色(对应动物类)

public interface Component {
void function();
}

具体构件角色(对应狗)

public class ConcreteComponent implements Component {

	@Override
public void function() {
System.out.println("基本功能:呼吸+觅食+睡觉");
} }

装饰角色

public class Decorator implements Component {

	private Component component; //持有一个Component类型的对象引用

	public Decorator(Component component) {
this.component = component;
} @Override
public void function() {
component.function(); //客户端的调用委派给具体的子类
} }

具体装饰角色(对应吼叫和吃肉这两个功能)

public class ConcreteDecorator extends Decorator {

	public ConcreteDecorator(Component component) {
super(component);
} @Override
public void function() {
super.function();
System.out.println("附加功能:");
this.eat();
this.bellow(); } private void eat() {
System.out.println("吃肉");
} private void bellow() {
System.out.println("吼叫");
}
}

客户端测试:

public class ClientTest {
public static void main(String[] args) {
Component component = new ConcreteComponent();
System.out.println("------装饰前:-------");
component.function();
Component newComponent = new ConcreteDecorator(component);
System.out.println("------装饰后:-------");
newComponent.function();
}
} 输出:
------装饰前:-------
基本功能:呼吸+觅食+睡觉
------装饰后:-------
基本功能:呼吸+觅食+睡觉
附加功能:吃肉+吼叫

四、应用

装饰者模式主要应用在Java的I/O流中,如果读者对I/O流体系比较混乱的话,不妨利用装饰者模式去理理思路。OutputStream和InputStream就对应于抽象构件角色(Component),FileInputStream和FileOutputStream就对应具体构件角色(ConcreteComponent),FilterOutputStream和FilterInputStream就对应着装饰角色(Decorator),而BufferedOutputStream,DataOutputStream等等就对应着具体装饰角色。

Java装饰者模式(Decorator)的更多相关文章

  1. 设计模式 - 装饰者模式(Decorator Pattern) Java的IO类 用法

    装饰者模式(Decorator Pattern) Java的IO类 用法 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26716 ...

  2. 装饰器模式-Decorator(Java实现)

    装饰器模式-Decorator(Java实现) 装饰器模式允许向一个现有的对象添加新的功能, 同时又不改变其结构. 其中 "现有对象"在本文中是StringDisplay类. 添加 ...

  3. 浅谈设计模式--装饰者模式(Decorator Pattern)

    挖了设计模式这个坑,得继续填上.继续设计模式之路.这次讨论的模式,是 装饰者模式(Decorator Pattern) 装饰者模式,有时也叫包装者(Wrapper),主要用于静态或动态地为一个特定的对 ...

  4. java装饰者模式理解

    java 装饰者模式其实就是扩展子类的功能,和继承是一个性质. 但继承是在编译时就固定扩展了父类的一些功能,而装饰者模式是在运行过程中动态绑定对象,实现一个子类可以随时扩展功能. 将方法排列组合,也可 ...

  5. 【PHP设计模式 09_ZhuangShiQi.php】装饰器模式 (decorator)

    <?php /** * [装饰器模式 (decorator)] * 有时候发布一篇文章需要经过很多人手,层层处理 */ header("Content-type: text/html; ...

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

    设计模式(八)装饰器模式Decorator(结构型) 1. 概述 若你从事过面向对象开发,实现给一个类或对象增加行为,使用继承机制,这是所有面向对象语言的一个基本特性.如果已经存在的一个类缺少某些方法 ...

  7. 设计模式 - 装饰者模式(Decorator Pattern) 具体解释

    装饰者模式(Decorator Pattern) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26707033 装饰者 ...

  8. 装饰者模式 Decorator

    项目:咖啡计费系统 背景:现有系统中有一个抽象类Beverage,有2个抽象方法GetDescription和Cost. namespace DecoratorPattern { /// <su ...

  9. 设计模式学习--装饰者模式(Decorator Pattern)

    概念: 装饰者模式(Decorator Pattern): 动态地将功能添加到对象,相比生成子类更灵活,更富有弹性. 解决方案: 装饰者模式的重点是对象的类型,装饰者对象必须有着相同的接口,也也就是有 ...

随机推荐

  1. C. Journey

    C. Journey time limit per test 2 seconds memory limit per test 256 megabytes input standard input ou ...

  2. GDI绘制图形的使用_验证码

    //创建GDI对象 Graphics g = this.CreateGraphics();// new Graphics(); //创建画笔对象 Pen pen = new Pen(Brushes.R ...

  3. oracle v$database 视图

    Select db.dbid "数据库标识",--数据库的标识,当数据库在所有文件的头部创建和存储时计算出来的标记编号       db.Name "数据库名称" ...

  4. Linux 安装Memcache扩展支持

    查看相关软件包 yum search memcached 安装memcache yum -y install memcachedMemcache关联php yum -y install php-pec ...

  5. Android商城开发系列(二)——App启动欢迎页面制作

    商城APP一般都会在应用启动时有一个欢迎界面,下面我们来实现一个最简单的欢迎页开发:就是打开商城App,先出现欢迎界面,停留几秒钟,自动进入应用程序的主界面. 首先先定义WelcomeActivity ...

  6. Mongodb之failed to create service entry worker thread

    Mongodb "failed to create service entry worker thread" 错误. 系统:CentOS release 6.8 mongod.lo ...

  7. thinkphp 的事务回滚处理 和 原始PHP的事务回滚实例

    1.  要程序里面支持事务,首先连接的数据库和数据表必须支持事务 mysql   为例: 数据库InnoDB支持 transactions 数据表支持事务:InnoDB  支持transaction ...

  8. 2012-2013 ACM-ICPC, NEERC, Central Subregional Contest J Computer Network1 (缩点+最远点对)

    题意:在连通图中,求一条边使得加入这条边以后的消除的桥尽量多. 在同一个边双连通分量内加边肯定不会消除桥的, 求边双连通分量以后缩点,把桥当成边,实际上是要选一条最长的链. 缩点以后会形成一颗树,一定 ...

  9. python基础一 day14 生成器函数进阶(1)

  10. shell脚本,awk取奇数行与偶数行方法。

    第一种方法: 第二种方法: 第三种方法: