Java设计模式篇(四)--装饰模式详解
程序员文章站
2022-07-12 20:35:40
...
我们来说一下装饰模式。
一、什么是装饰模式
装饰模式也叫包装模式,使用它可以给指定对象增强原有功能,用于扩展原有功能。相比于子类继承,装饰模式提供了更好的灵活性。而对于使用者来说,这个过程是透明的,调用方式没有发生变化。
二、装饰模式的结构图
从结构图我们可以看到,在装饰模式中存在的角色:
- 抽象组件角色(Component):在抽象组件接口类中,抽象出要增强的功能接口。
- 具体组件角色(ConcreteComponent):实际就是被装饰者对象类,实现了抽象组件接口,用来定义一个实实在在的对象,给此对象进行功能增强。
- 装饰角色父类(Decorator):在装饰角色父类中,持有抽象组件角色的对象,实现了抽象组件角色接口,这样,当抽象组件进行实例化的时候,可以明确知道要给哪个对象增加职责。这么做的目的是为了实现扩展和可复用,并且对于被装饰者对象而言,这个过程是透明的。
- 具体装饰类角色(ConcreteDecorator):定义具体的装饰行为实现。
三、用法举例
我们举一例,比如,西游记中,孙大圣为了降伏妖怪,迫不得已的时候需要利用72般变化。72般变化为增强降伏妖怪的过程变得生动精彩。我们的孙大圣是什么?一只猴子。我们先来画类图:
1、我们先定义大圣打妖怪这个接口类。
package com.zhaodf.pattern.decoratorPattern; public interface PlayDevil{ void playTheDevil(); }
2、定义大圣本尊
package com.zhaodf.pattern.decoratorPattern; public class Sunstory implements PlayDevil{ public void playTheDevil() { System.out.println("孙大圣打妖怪"); } }
3、定义装饰类:孙大圣要变化
package com.zhaodf.pattern.decoratorPattern; public class MythChange implements PlayDevil{ private PlayDevil playDevil; public MythChange(PlayDevil playDevil){ this.playDevil = playDevil; } public void playTheDevil() { playDevil.playTheDevil(); } }
4、定义具体装饰类角色
大圣变蜜蜂:
package com.zhaodf.pattern.decoratorPattern; public class MythChangeToBee extends MythChange{ public MythChangeToBee(PlayDevil playDevil) { super(playDevil); } @Override public void playTheDevil() { System.out.println("孙大圣变成了蜜蜂"); } }
大圣变小鱼:
package com.zhaodf.pattern.decoratorPattern; public class MythChangeToFish extends MythChange{ public MythChangeToFish(PlayDevil playDevil) { super(playDevil); } @Override public void playTheDevil() { System.out.println("孙大圣变成了鱼儿"); } }
5、客户端类
package com.zhaodf.pattern.decoratorPattern; public class TestDecorator { public static void main(String[] args){ PlayDevil playDevil = new Sunstory(); PlayDevil playDevilToFish = new MythChangeToBee(playDevil); playDevilToFish.playTheDevil(); } }
运行结果:
四、装饰者模式在Java IO中的使用
装饰者模式是Java I/O库的基本模式。我们看下IO库的设计类图:
Java I/O库提供了多种功能的文件读取解析组合,如果这些类都是用继承的方法实现的,那么每一种组合都需要一个类,这样就会造成大量重复功能类的出现。而设计者采用装饰者模式,这么做就大大减少了功能重复类的出现。
根据类图中我们可以看到:
- 抽象组件角色(Component):由InputStream扮演。这是一个抽象类,为各种子类型提供统一的接口。
- 具体组件角色(ConcreteComponent):由ByteArrayInputStream、FileInputStream、PipedInputStream、StringBufferInputStream等类扮演。它们实现了抽象构件角色所规定的接口。
- 装饰角色父类(Decorator):由FilterInputStream扮演。它实现了InputStream所规定的接口。
- 具体装饰类角色(ConcreteDecorator):由几个类扮演,分别是BufferedInputStream、DataInputStream以及两个不常用到的类LineNumberInputStream、PushbackInputStream。
上一篇: Java设计模式中软件的设计原则篇
下一篇: 2017年问题汇总-待整理