博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java 装饰器模式详解
阅读量:6713 次
发布时间:2019-06-25

本文共 2838 字,大约阅读时间需要 9 分钟。

转载请注明出处:

前言

在上面的几篇文章中,着重介绍了java 中常见的 IO 相关知识,在学习的过程中,发现 IO 包中是用了大量的装饰器模式,为了彻底的学习 IO,今天就来揭开装饰器模式的面纱。

为了弄明白装饰器模式的本质,我查看了很多资料,发现有很多文章要么说的很苦涩,要么举的例子不恰当。

其实我们可以这样理解装饰器模式, 就拿自己举例子,你把自己裸体的样子,想象成被装饰的对象。你的鞋子,你的寸衣,你的外套,你的手表,你的帽子 等等,都是你的装饰物,你和这些装饰物,是装饰和被装饰的关系。

实例展示

好了,现在我们用代码的方法去理解这样概念。

首先,我们发现,不管是裸体的人,还是你的鞋子、帽子,都有展示的功能,我们称之为show 方法。

我们定义一个接口,它具有展示的功能,也就是show() , 

package com.user;/** * 定义接口 * @author T * */public interface AbstractPerson {	//具有展示的功能	void show() ;}
现在应该定义一个裸体的自己了,Me 类

package com.user;/** * 定义一个具体的人,就是被装饰者 * @author T * */public class Me implements AbstractPerson {	@Override	public void show() {		System.out.println( "什么都没穿,我展示的是裸体");	}}
下面该定义,鞋子,帽子,手表等 装饰物,等等先别急,我们应该先定义一个鞋子,帽子,手表的抽象父类 
AbstractClothes 。 
其实抽象的父类有一个构造函数,构造函数里面的参数是抽象的人类,这里的用法很巧妙,这也是能够实现装饰功能的一个必不可少的步骤。

package com.user;/** * 定义抽象装饰物 * @author T * */public abstract class AbstractClothes implements AbstractPerson {	AbstractPerson abstractPerson ;	public AbstractClothes( AbstractPerson abstractPerson ){		this.abstractPerson = abstractPerson ;	}	@Override	public void show() {		abstractPerson.show();	}}
下面开始定义,帽子装饰物  Hat 类, 继承 AbstractClothes 类

package com.user;/** * 帽子装饰物 * @author T * */public class Hat extends AbstractClothes {	public Hat(AbstractPerson abstractPerson) {		super(abstractPerson);	}		@Override	public void show() {		super.show();	    say();	}		public void say(){		System.out.println( "我展示一个帽子");	}}
定义鞋子装饰类 Shoes ,   继承 AbstractClothes 类

package com.user;/** * 鞋子装饰物 * @author T * */public class Shoes extends AbstractClothes {	public Shoes(AbstractPerson abstractPerson) {		super(abstractPerson);	}		@Override	public void show() {		super.show();	    say();	}		public void say(){		System.out.println( "我展示一双鞋子");	}}

创建测试类 Test

package com.user;public class Test {	public static void main(String[] args) {		//创建被装饰者		Me me = new Me() ;		//裸体的人被装饰了帽子 ,具有了展示帽子的能力		Hat hat = new Hat( me ) ;		// 带了帽子的人被装饰了鞋子,具有了展示鞋子的本领		Shoes shoes = new Shoes( hat ) ;		shoes.show();	}}
运行结果:

什么都没穿,我展示的是裸体我展示一个帽子我展示一双鞋子

装饰器模式的类图

在学习完了一个小例子之后,我们试着总结出装饰器模式的类图。

装饰器模式类图:

  • Component抽象构件角色:真实对象和装饰对象有相同的接口。这样,客户端对象就能够以与真实对象相同的方式同装饰对象交互。
  • ConcreteCompoent具体构建角色(真实对象):定义一个将要接收附加责任的类。
  • Decorator装饰角色:持有一个抽象构件的引用。装饰对象接受所有客户端的请求,并把这些请求转发给真实的对象。这样,就能在真实对象调用前后增加新的功能。
  • ConcreteDecorate具体装饰角色:负责给构件对象增加新的功能。

装模式在Java I/O库中的应用

IO流实现细节:

  • Component抽象构件角色:io流中的InputStream,OutputStream,Reader,Writer
  • ConcreteComponent具体构件角色:io流中的FileInputStream,FileOutputStream
  • Decorate装饰角色:持有抽象构件的引用,FilterInputStream,FilterOutputStream
  • ConcreteDecorate具体装饰角色:负责给构件对象添加新的责任,BufferedInputStream,BufferedOutputStream等

总结

  • 装饰模式(Decorate)也叫包装模式(Wrapper)
  • 装饰模式降低系统的耦合度,可以动态的增加或删除对象的责任,并使得需要装饰的具体构建类和具体装饰类可以独立变化,以便增加新的具体构建类和具体装饰类。

优点

  •  扩展对象功能,比继承灵活,不会导致类个数急剧增加。
  • 可以对一个对象进行多次装饰,创造出不同行为的组合,得到功能更加强大的对象。
  • 具体构 件 类和具体装饰类可以独立变化,用户可以根据需要自己增加新的 具体构件子类和具体装饰子类。

缺点

  • 产生很多小对象。大量小的对象占据内存,一定程度上影响性能。
  • 装饰模式易出错,调试排查比较麻烦。

参考资料:

你可能感兴趣的文章
golang ubuntu开发环境
查看>>
ArcGIS Server 10.2 实战(三)图层标注及图例中文显示乱码的解决
查看>>
Win7关机时弹出对话框,提示你想要的信息
查看>>
Linux初学(三)
查看>>
java中的链式编程
查看>>
正确率、召回率、F值
查看>>
kuangbin专题十二 HDU1078 FatMouse and Cheese )(dp + dfs 记忆化搜索)
查看>>
多行文本超出显示省略号
查看>>
转载~基于比较的排序算法的最优下界为什么是O(nlogn)
查看>>
在本机通过SQL远程操作数据库
查看>>
StringMVC返回字符串
查看>>
Windows完成端口网络模型
查看>>
CSS Hack整理
查看>>
leetcode 28. Implement strStr()
查看>>
nginx 服务器重启命令,关闭 (转)
查看>>
实用的正则表达式
查看>>
Hibernate中Criteria的完整用法
查看>>
LINUX创建用户的命令
查看>>
Spring MVC 学习总结(一)——MVC概要与环境配置 转载自【张果】博客
查看>>
POJ 2728 二分+最小生成树
查看>>