Java 装饰器模式详解-阿里云开发者社区

开发者社区> 赵彦军521> 正文

Java 装饰器模式详解

简介: 转载请注明出处:http://blog.csdn.net/zhaoyanjun6/article/details/56488020 前言 在上面的几篇文章中,着重介绍了java 中常见的 IO 相关知识,在学习的过程中,发现 IO 包中是用了大量的装饰器模式,为了彻底的学习 IO,今天就来揭开装饰器模式的面纱。
+关注继续查看

转载请注明出处:http://blog.csdn.net/zhaoyanjun6/article/details/56488020


前言

在上面的几篇文章中,着重介绍了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)
  • 装饰模式降低系统的耦合度,可以动态的增加或删除对象的责任,并使得需要装饰的具体构建类和具体装饰类可以独立变化,以便增加新的具体构建类和具体装饰类。

优点

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

缺点

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

参考资料:

Java设计模式学习09——装饰模式

Java与模式:装饰(Decorator)模式



版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
7425 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,大概有三种登录方式:
2541 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
9140 0
使用SSH远程登录阿里云ECS服务器
远程连接服务器以及配置环境
2131 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
10744 0
腾讯云服务器 设置ngxin + fastdfs +tomcat 开机自启动
在tomcat中新建一个可以启动的 .sh 脚本文件 /usr/local/tomcat7/bin/ export JAVA_HOME=/usr/local/java/jdk7 export PATH=$JAVA_HOME/bin/:$PATH export CLASSPATH=.
4462 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
6018 0
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
2966 0
+关注
赵彦军521
Android开发者
217
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《Nacos架构&原理》
立即下载
《看见新力量:二》电子书
立即下载
云上自动化运维(CloudOps)白皮书
立即下载