设计模式学习之装饰模式:IO流的装饰器

IO流的装饰器

题目分析:通过对java的io系列类分析得知,java的io流使用了设计模式中的装饰模式,以动态的给一个对象增加职责,能够更加灵活的增加功能。通过看io的源代码得知FilterOutputStream类继承了OutputStream类并拥有父类的一个对象,它和父类具有组合聚合的关系。因此要实现我们自己的加密类只需扩展FilterOutputStream类重写它的wite方法即可

UML图:

源代码:

package com.cmc
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
//加密类,扩展了FilterOutputStream 类并重写了write方法
public class EncryptOutputStream extends FilterOutputStream {
	public EncryptOutputStream(OutputStream out) {
		super(out);
	}
	public void write(int arg) throws IOException {
        arg += 2;
        if (arg >= 97 + 26) {
            arg = arg - 26;
        }
        super.write(arg);
    }
}
package com.cmc;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
//客户端测试
public class Client {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		OutputStream os = null;
		try {
			os = new EncryptOutputStream(
new BufferedOutputStream(
new FileOutputStream(
new File("text.txt"))));
			os.write("qwerty".getBytes());
			os.flush();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally{
			try {
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

执行后text.txt中的内容为:sygtv

优点

1、装饰者模式可以提供比继承更多的灵活性

2、可以通过一种动态的方式来扩展一个对象的功能,在运行时选择不同的装饰器,从而实现不同的行为。

3、通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。可以使用多个具体装饰类来装饰同一对象,得到功能更为强大的对象。

4、具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”。

缺点

1、会产生很多的细粒度对象,增加了系统的复杂性

2、这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。

出现问题:java的io流概念较难理解

解决办法:查看java的io包下的源代码,并查阅API了解它的继承关系

时间: 2024-10-12 21:11:52

设计模式学习之装饰模式:IO流的装饰器的相关文章

Java IO流以及装饰器模式在其上的运用

流概述 Java中,流是一种有序的字节序列,可以有任意的长度.从应用流向目的地称为输出流,从目的地流向应用称为输入流. Java的流族谱 Java的 java.io 包中囊括了整个流的家族,输出流和输入流的谱系如下所示: InputStream和OutputStream InputStream和OutputStream分别是输入输出流的顶级抽象父类,只定义了一些抽象方法供子类实现. 在输出流OutputStream中,如果你需要向一个输出流写入数据,可以调用 void write(int b)

IOS设计模式之二(门面模式,装饰器模式)

本文原文请见:http://www.raywenderlich.com/46988/ios-design-patterns. 由 @krq_tiger(http://weibo.com/xmuzyq)翻译,如果你发现有什么错误,请与我联系谢谢. 门面(Facade)模式(译者注:facade有些书籍译为门面,有些书籍译为外观,此处译为门面) 门面模式针对复杂的子系统提供了单一的接口,不需要暴漏一些列的类和API给用户,你仅仅暴漏一个简单统一的API. 下面的图解释了这个概念: 这个API的使用者

《java与设计模式》之装饰模式详解&Java IO中的装饰器模式

1 概述 在一个项目中,你会有非常多的因素考虑不到,特别是业务的变更,不时的冒出一个需求是很正常的情况.有三个继承关系的类:Father.Son.GrandSon,我们要在Son类上增强一些功能怎么办?给Son类增加方法吗?那对GrandSon的影响呢?特别是对GrandSon有多个的情况,你会怎么办?认真看完本文,你会找到你的答案. JavaIO中,像下面的嵌套语句是不是很常见,为什么要怎样定义呢?理解装饰模式后,你会找到答案. DataInputStream in = new DataInp

[javaSE] IO流(装饰设计模式)

装饰设计模式:当想要对已有的对象进行功能增强时,可以自定义类将已有的对象传入,并提供加强功能,自定义的该类称为装饰类 典型的: Reader--FileReader --BufferedReader class Decorator{ public void eat(){ System.out.println("吃饭"); } } public class DecoratorDemo extends Decorator{ public DecoratorDemo() { } public

Java设计模式学习记录-装饰模式

前言 装饰模式也是一种结构型模式,主要是目的是相对于类与类之间的继承关系来说,使用装饰模式可以降低耦合度.JDK中有不少地方都使用到了装饰模式,例如Java的各种I/O流,javax.swing包中一些图形界面构件功能的增强等地方都运用了装饰模式. 装饰模式 定义 装饰模式的定义是:在不改变原类文件以及不使用继承的情况下,动态的扩展一个对象的功能.装饰模式是通过创建一个包装对象来实现的,也就是用装饰来包裹真实的对象. 举例 还是老规矩,举例说明,在给亲朋好友过生日时会买生日蛋糕,然后生日蛋糕又有

IO流与装饰者模式

java使用IO流来处理不同设备之间数据的交互;所有的IO操作实际上都是对 Stream 的操作 从功能上划分: 输入流: 当数据从源进入的编写的程序时,称它为输入流; 输出流: 从程序输出回另一个源成为输出流; 输入与输出是有参照物的,而这个参照物就是应用程序本身 从结构上划分: 总体的大纲分为两部分,字节流和字符流的封装类体系 首先说: 什么是字节流? 按照字节读取的流对象,一次读取一个字节 1字节 占八位 一个数字占四个字节, (前三个八位补0) 什么是字符流? 按照字符读取的流对象,一次

JavaSE 学习笔记之IO流(二十二)

IO流:用于处理设备上数据. 流:可以理解数据的流动,就是一个数据流.IO流最终要以对象来体现,对象都存在IO包中. 流也进行分类: 1:输入流(读)和输出流(写). 2:因为处理的数据不同,分为字节流和字符流. 字节流:处理字节数据的流对象.设备上的数据无论是图片或者dvd,文字,它们都以二进制存储的.二进制的最终都是以一个8位为数据单元进行体现,所以计算机中的最小数据单元就是字节.意味着,字节流可以处理设备上的所有数据,所以字节流一样可以处理字符数据. 那么为什么要有字符流呢?因为字符每个国

java基础学习笔记之IO流

1.IO流用来处理设备之间的数据传输方向:硬盘通过“读reader”完成对内存的读取,内存通过“写writer”完成对硬盘的写入2.Java对数据的操作是通过流的方式3.Java用于操作流的对象都在IO包中4.流按操作数据分为两种:字节流和字符流--字符流的由来:>>字节流读取文字字节数据后,不直接操作而是先查指定的编码表.获取对应的文字.再对这个文字进行操作.简单说:字符流=字节流+编码表--字节流的两个顶层父类:1.InputStream 2.OutputStream--字符流的两个顶层父

黑马程序员--Java基础学习笔记【IO流-字节流、转换流】

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- IO 流 常用基类 字节流 InputStreamOutputStream 常用方法 int read() // 读取一个字节,以 int 形式返回 intread(byte[] b) // 读取最多数组长度个字节并存入该数组,返回实际读取字节 void write(int d) // 写出一个字节 voidwrite(byte[] d) // 将给定字节数组中的所有字节全部写出 void w