装饰者模式 Decorator Pattern
Posted 有且仅有
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了装饰者模式 Decorator Pattern相关的知识,希望对你有一定的参考价值。
父博文地址:设计模式 - Design Patterns
一、是什么
问题
使用继承是静态的扩展:
- 随着系统功能增多造成了类数量指数级增加。
- 且基类的功能并不适用于所有子类。
寻找一个设计模式原则
开闭原则:类应该对扩展开放,对修改关闭。换句话说:在不修改类的前提下扩展类。
装饰者模式定义
动态的将责任附加到对象 上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
类图如下:
二、问答
AbstractDecorator
及其子类依然继承自AbstractComponent
不是吗?我们依然使用了继承,的确如此。不过这么做的重点在于,装饰者和被装饰者需要是同一个类型,这很关键。我们只是利用继承达到“类型匹配”,而不是利用继承获取“行为”。
加入行为
我们不是通过继承来“加入新行为”,而是通过“组合”。
为什么装饰者是抽象类?
通常使用抽象类,当然Java 中也可以使用接口,此时需要把构造函数定义在各个装饰者子类中。
三、实例
1. FilterInputStream
是InputStream
的装饰器
类图如下:
介绍
InputStream
是抽象被装饰类,ObjectInputStream
,FileInputStream
,ByteArrayInputStream
等是可以被装饰的具体组件。FilterInputStream
是装饰者类(这里没有设计为抽象),BufferedInputStream
,LineNumberInputSream
,DataInputSream
等是具体的装饰者类。FilterInputStream
代码public class FilterInputStream extends InputStream protected volatile InputStream in; protected FilterInputStream(InputStream in) this.in = in; public int read() throws IOException return in.read(); // others
可以看到,包装类只有一个有参数的构造函数,参数是被包装类。包装类可以动态的添加功能,这里覆盖了
read()
并简单的调用被包装类的同名方法。一个可能的用例
FileInputSream
被BufferedInputSream
装饰,BufferedInputSream
又被LineNumberInputSream
装饰。
以上是关于装饰者模式 Decorator Pattern的主要内容,如果未能解决你的问题,请参考以下文章
Java设计模式之——装饰者模式(Decorator pattern)
设计模式 —— 装饰器模式(Decorator Pattern)