什么是装饰者模式

装饰者模式(Decorator Pattern,有的也用 Wrapper Pattern)就是动态地把职责附加到已有对象上去,实现功能扩展。这种特性,使得装饰者模式提供了比继承更具有弹性的解决方案。

提到装饰者模式,总让我想起卞之琳的《断章》来:

你站在桥上看风景,

看风景的人在楼上看你。

明月装饰了你的窗子,

你装饰了别人的梦。

多么有意境啊,单身狗读完会不会觉得心好累,没关系,我来拯救你!

装饰者模式类图

送你一个女朋友怎么样!想她是美国金发大妞?浪漫的法国女郎?国产的萌萌哒妹子?OK,没问题!你想她是哪个国家的就是哪个国家的。她们有不同的爱好或者习惯,每一个这样的女孩,都可以看作是一个 Java 类。我知道此刻你一定在想,这一个、那一个...那岂不是有很多类?这种方式没有扩展性,每当有一个新类型的女孩,就得又新建一个类,这简直就是类爆炸啊!

装饰者模式示例代码

在project下新建Test.java(下面的代码块中是全部的代码,实际操作中应当按注释创建相应的类再将方法写入对应的类中)

// 抽象类 Girl
abstract class Girl {String description = "no particular";public String getDescription(){return description;}
}// 美国女孩
class AmericanGirl extends Girl {public AmericanGirl() {description = "+AmericanGirl";}
}// 国产妹子
class ChineseGirl extends Girl {public ChineseGirl() {description = "+ChineseGirl";}
}// 装饰者
abstract class GirlDecorator extends Girl {public abstract String getDescription();
}// 下面以美国女孩示例
// 给美国女孩加上金发
class GoldenHair extends GirlDecorator {private Girl girl;public GoldenHair(Girl g) {girl = g;}@Overridepublic String getDescription() {return girl.getDescription() + "+with golden hair";}}// 加上身材高大的特性
class Tall extends GirlDecorator {private Girl girl;public Tall(Girl g) {girl = g;}@Overridepublic String getDescription() {return girl.getDescription() + "+is very tall";}}// 检验一下
public class Test {public static void main(String[] args) {Girl g1 = new AmericanGirl();System.out.println(g1.getDescription());GoldenHair g2 = new GoldenHair(g1);System.out.println(g2.getDescription());Tall g3 = new Tall(g2);System.out.println(g3.getDescription());// 你也可以一步到位// Girl g = new Tall(new GoldenHair(new AmericanGirl())); }
}

输入命令编译运行:

javac Test.java
java Test

最后美国金发大妞奉上(输出内容为): 

装饰者模式应用

当你需要动态地给一个对象添加功能,实现功能扩展的时候,就可以使用装饰者模式。

Java IO 类中有一个经典的装饰者模式应用, BufferedReader 装饰了 InputStreamReader.

BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
  • InputStreamReader(InputStream in) - InputSteamReader 读取 bytes 字节内容,然后转换成characters流输出。

  • BufferedReader(Reader in) - 从 characters 流中读取内容并缓存。

装饰者模式、适配器模式区别

  1. 关于新职责:适配器也可以在转换时增加新的职责,但其主要目的并不在此;而装饰者模式主要目的,就是给被装饰者增加新职责用的。

  2. 关于原接口:适配器模式是用新接口来调用原接口,原接口对新系统来说是不可见或者说不可用的;而装饰者模式原封不动的使用原接口,系统对装饰的对象也通过原接口来完成使用。

  3. 关于其包裹的对象:适配器是知道被适配者的详细情况的(就是那个类或那个接口);而装饰者只知道其接口是什么,至于其具体类型(是基类还是其他派生类)只有在运行期间才知道。

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

  1. java/android 设计模式学习笔记(7)---装饰者模式

    这篇将会介绍装饰者模式(Decorator Pattern),装饰者模式也称为包装模式(Wrapper Pattern),结构型模式之一,其使用一种对客户端透明的方式来动态的扩展对象的功能,同时它也是 ...

  2. 设计模式学习笔记(三)-装饰者模式

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

  3. java学习笔记十三

    11. 凡是继承了FilterOutputStream或FilterInputStream的类都是过滤流,也就是说他们不能直接跟目标(键盘,文件,网络等,节点流可以)数据打交道,只能包装 Intput ...

  4. 《Java学习笔记(第8版)》学习指导

    <Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...

  5. java学习笔记13--反射机制与动态代理

    本文地址:http://www.cnblogs.com/archimedes/p/java-study-note13.html,转载请注明源地址. Java的反射机制 在Java运行时环境中,对于任意 ...

  6. java学习笔记11--Annotation

    java学习笔记11--Annotation Annotation:在JDK1.5之后增加的一个新特性,这种特性被称为元数据特性,在JDK1.5之后称为注释,即:使用注释的方式加入一些程序的信息. j ...

  7. 准备写java学习笔记

    准备写java学习笔记 java int 转载于:https://blog.51cto.com/cryingcloud/1975267

  8. Java设计模式(装饰者模式-组合模式-外观模式-享元模式)

    Java设计模式Ⅳ 1.装饰者模式 1.1 装饰者模式概述 1.2 代码理解 2.组合模式 2.1 组合模式概述 2.2 代码理解 3.外观模式 3.1 外观模式概述 3.2 代码理解 4.享元模式 ...

  9. Java学习笔记--StringTokenizer的使用

    2019独角兽企业重金招聘Python工程师标准>>> Java Tips: 使用Pattern.split替代String.split String.split方法很常用,用于切割 ...

  10. java学习笔记12--异常处理

    java学习笔记系列: java学习笔记11--集合总结 java学习笔记10--泛型总结 java学习笔记9--内部类总结 java学习笔记8--接口总结 java学习笔记7--抽象类与抽象方法 j ...

最新文章

  1. 一个为制造业而生的AI助手,普通员工向它提问就能做数据分析
  2. iis日志转到sql存储
  3. analyze table tablename
  4. 小程序 -- [sitemap 索引情况提示] 根据 sitemap 的规则[0],当前页面 [pages/index/index] 将被索引
  5. ssh(Spring+Spring mvc+hibernate)——IDeptService.java和IEmpService.java
  6. js 高级应用 自定义事件
  7. 计算机操作系统(第四版)课后习题答案西电版V2.0校对版
  8. 东芝计算机配置,东芝Toshiba笔记本电脑开机进入BIOS的方法与bios设置参数介绍(ESC+F1)...
  9. oracle10g的系统视图(sys、system)
  10. [渝粤教育] 中央财经大学 宏观经济学 参考 资料
  11. Python爬虫-豆瓣电影排行榜TOP250
  12. 易语言选单选框分组框API全选取消
  13. Redis - CLUSTER命令中槽管理命令详解
  14. 影像数据的分辨率与比例尺关系
  15. 抖音60秒视频权限开通方法
  16. iOS 15增加更多新的小组件
  17. wxpython后台线程更新界面控件方法
  18. PTA(每日一题)7-43 验证哥德巴赫猜想
  19. Mysql:报错:error while loading shared libraries: libaio.so.1:
  20. 20189220 余超《Linux内核原理与分析》第九周作业

热门文章

  1. HDU 1325 Is It A Tree?(并查集)
  2. xcode 调试提示
  3. Careercup - Microsoft面试题 - 5680049562845184
  4. 鉴客 C# 抓取页面(带认证)
  5. 见过NTP服务,没见过网络流量到200M左右的NTP服务
  6. JQuery each详细用法
  7. 电子商务入门、实操、行业分析及公司案例等精彩系列问答有哪些?
  8. Redis的持久化机制:RDB和AOF
  9. mysql日常工作中批量插入效率问题
  10. 并发编程学习之volatile关键字