装饰者模式
    动态的将责任附加到对象上。若要扩展功能,装饰者模式提供了比继承更有弹性的替代方案。
说明:
1、装饰者和被装饰者对象有相同的超类型;
2、可以用一个或者多个装饰者包装一个对象;
3、既然装饰者和被装饰者对象有相同的超类型,所以在任何需要原始对象(被装饰者)的场合,可以用装饰过的对象代替它;
4、装饰者可以在委托被装饰者的行为之前 与 / 或 之后,加上自己的行为,以达到特定的目的
5、对象可以在任何时候被装饰,所以可以在运行时动态地、不限量地用你喜欢的装饰者来装饰对象。

在装饰模式中的角色有:

抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。

具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类。

装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。

具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任。

/**
* 孙悟空的本尊,并且定义了七十二变的方法。
* 抽象构件(Component)角色
*/
public abstract class Monkey {
protected String type = "本尊";
protected abstract void change();
public String getType() {
return type;
}
}

/**
* 齐天大圣
* 具体构件(ConcreteComponent)角色
* */
public class MonkeyKing extends Monkey{
public MonkeyKing() {
type = "齐天大圣 -> ";
}
@Override
protected void change() {
System.out.println("七十二变......");
}
}

/**
* 变化的孙悟空
* 装饰(Decorator)角色
* */
public abstract class ChangeMonkey extends Monkey{
@Override
protected abstract void change();
}

/**
* 变化后为鱼
* 具体装饰(ConcreteDecorator)角色
* */
public class Fish extends ChangeMonkey{
private Monkey monkey;
public Fish(Monkey monkey) {
this.monkey = monkey;
}
@Override
protected void change() {
System.out.println("变化为 Fish ......");
}
public String getType() {
return monkey.getType() + "fish -> ";
}
}

/**
* 变化后为鸟
* 具体装饰(ConcreteDecorator)角色
* */
public class Bird extends ChangeMonkey{
private Monkey monkey;
public Bird(Monkey monkey) {
this.monkey = monkey;
}
@Override
protected void change() {
System.out.println("Bird......");
}
public String getType() {
return monkey.getType() + "bird -> ";
}
}

public class Client {
public static void main(String[] args) {
Monkey monkey = new MonkeyKing();
Monkey fish = new Fish(monkey);
Monkey fish2 = new Fish(fish);
Monkey bird = new Bird(fish2);
System.out.println(bird.getType());
bird.change();
}
}
    装饰着模式在 Java I/O 中的应用

根据上图可以看出:

  ●  抽象构件(Component)角色:由InputStream扮演。这是一个抽象类,为各种子类型提供统一的接口。

  ●  具体构件(ConcreteComponent)角色:由ByteArrayInputStream、FileInputStream、PipedInputStream、StringBufferInputStream等类扮演。它们实现了抽象构件角色所规定的接口。

  ●  抽象装饰(Decorator)角色:由FilterInputStream扮演。它实现了InputStream所规定的接口。

  ●  具体装饰(ConcreteDecorator)角色:由几个类扮演,分别是BufferedInputStream、DataInputStream以及两个不常用到的类LineNumberInputStream、PushbackInputStream。

装饰模式的优点

  (1)装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。装饰模式允许系统动态决定“贴上”一个需要的“装饰”,或者除掉一个不需要的“装饰”。继承关系则不同,继承关系是静态的,它在系统运行前就决定了。

  (2)通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

装饰模式的缺点

  由于使用装饰模式,可以比使用继承关系需要较少数目的类。使用较少的类,当然使设计比较易于进行。但是,在另一方面,使用装饰模式会产生比使用继承关系更多的对象。更多的对象会使得查错变得困难,特别是这些对象看上去都很相像。

参考资料:《Head First 设计模式》
http://www.cnblogs.com/java-my-life/archive/2012/04/20/2455726.html

转载于:https://www.cnblogs.com/LeslieXia/p/5494793.html

设计模式学习笔记之装饰者模式相关推荐

  1. 研磨设计模式学习笔记之装饰器模式

    1.装饰器模式定义:动态地给一个对象添加一些额外的功能职责,就增加功能来说,装饰器模式要比生成子类更加灵活. 2.装饰器模式实现:在装饰器模式的实现中,为了能够实现和原来使用被装饰对象的代码无缝隙结合 ...

  2. 设计模式学习笔记——享元(Flyweight)模式

    设计模式学习笔记--享元(Flyweight)模式 @(设计模式)[设计模式, 享元模式, flyweight] 设计模式学习笔记享元Flyweight模式 基本介绍 享元案例 类图 实现代码 Big ...

  3. 设计模式学习笔记——中介者(Mediator)模式

    设计模式学习笔记--中介者(Mediator)模式 @(设计模式)[设计模式, 中介者模式, Mediator] 设计模式学习笔记中介者Mediator模式 基本介绍 中介者案例 类图 实现代码 Me ...

  4. 设计模式学习笔记——单例(Singleton)模式

    设计模式学习笔记--单例(Singleton)模式 @(设计模式)[设计模式, 单例模式, Singleton, 懒汉式, 饿汉式] 设计模式学习笔记单例Singleton模式 基本介绍 单例案例 类 ...

  5. 设计模式学习笔记--Mediator 中介者模式

    我们知道面向对象应用程序是由一组为了提供某种服务而彼此交互的对象组成.当彼此引用的对象数量比较少时,此时对象之间就为直接交互(点对点).而当对象的数量增加时,这种直接交互会导致对象之间复杂的.混乱的引 ...

  6. 设计模式学习笔记--Flyweight享元模式

    Flyweight模式也叫享元模式,是由GoF提出的23种设计模式中的一种.Flyweight模式是构造型模式之一,它通过与其他类似对象共享数据来减小内存占用,所以叫享元.   此模式解决的是由于大量 ...

  7. 设计模式学习笔记--享元(Flyweight)模式

    写在模式学习之前 什么是设计模式:在我们进行程序设计时,逐渐形成了一些典型问题和问题的解决方案,这就是软件模式:每一个模式描述了一个在我们程序设计中经常发生的问题,以及该问题的解决方案:当我们碰到模式 ...

  8. C#设计模式学习笔记:(4)建造者模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7614630.html,记录一下学习过程以备后续查用.一.引言在现实生活中,我们经常会遇到一些构成比较复杂的物 ...

  9. 设计模式学习笔记(八)—Template Method模式

    factory模式(包括简单工厂和抽象工厂),Strategy模式,Template method模式是学习Spring框架必不可少的. <设计模式>一书对Template Method模 ...

最新文章

  1. 硬盘突然提示没有初始化_分享一下固态硬盘不认盘的修复方法
  2. windows环境下redis.conf配置文件
  3. DEAP:使用生理信号进行情绪分析的数据库(一、背景介绍与刺激选择)
  4. LINQ to SQL语句(4)之Join
  5. CentOS部署SpringBoot项目(二)
  6. linux下的C语言开发(多线程编程)
  7. outlook 邮件 设置延迟送信
  8. java hql 连接查询,java – 如何从HQL表单中的两个连接表查询中选择*?
  9. android 把数据导入到excel文件中的三种方法
  10. AI上推荐 之 NeuralCF与PNN模型(改变特征交叉方式)
  11. 实现手机扫描二维码页面登录,类似web微信-第三篇,手机客户端
  12. Java包装类及自动装箱、拆箱
  13. vue 导出word文档,支持表格和图片
  14. 怎么能看出一个人开车水平高低?
  15. Wireshark 基础 | 捕获过滤篇
  16. IOS开发协议使用之──非正式协议和正式协议
  17. ASP.NET入门教程(经典)
  18. python实现AdaBoost算法
  19. .net 4.5 MVC5 降级至 .net 4.0 MVC 4
  20. 计算机网络规划教学,计算机网络教学计划.doc

热门文章

  1. 前端教程:HTML5有哪些新特性?
  2. Nuxt使用cookies踩坑之设置axios的header
  3. 《Power Designer系统分析与建模实战》——1.4 本章小结
  4. 排序总结---常用的排序算法总结,java和js实现
  5. Hibernate实体对象的生命周期(三种状态详解)
  6. 3.5框架不能创建就加这一段代码
  7. 网站左侧悬浮框随着滚动条滚动代码
  8. LeetCode 84. Largest Rectangle in Histogram
  9. 【CS229】监督学习 vs. 无监督学习
  10. 三重积分先二后一和先一后二的碎碎念