装饰者模式在Java I/O中的应用
2016-06-10 15:01
786 查看
首先来说说什么是装饰者模式,装饰责模式的主要就是动态地给一个对象添加一些额外的职责或者行为。这种方式比继承来的更加的灵活,下面的他的各个组件关系图。
分析一下各个组件:
Component(抽象组件角色):-被装饰对象的统一接口
ConcreteComponent(具体组件角色):-被装饰者
Decorator(抽象装饰器):-维持一个指向构件Component对象的实例
ConcreteDecorator(具体装饰器角色): -添加职责
其实这样看还是很抽象的,下面就借用JDK中的关于这个模式的应用,在Java I/O中就应用了装饰者设计模式,来看一下类图结构。
可以看到输入流有一个共同的基类,就是InputStream这个类在这个模式中扮演了Component的角色。
来看一下一个简化图吧~
可以看到这个FilterInputStream的类是非常重要的,下面是部分代码
可以看到这个类继承了一个InputStream,还聚合了一个InputStream,他的构造方法会传入一个InputStream这个类的作用就是装饰传来的输入流,看类的结构可以看出来继承FilterInputStream的类都是装饰类,他们数据的来源的别的输入流。
其实整个装饰者的思想就是用一些小部件来装饰一样东西,在生活中非常常见,比如说买咖啡的时候,一般先是一个普通的咖啡,你可以选择向里面添加糖或者牛奶或者冰块或者一些其他的东西,如果我们在设计一群这样类的时候采用继承的方式,每添加一个配料都要添加无数个种类的类,这样简直的类爆炸,所以我们会采用装饰者设计模式,用配料去装饰基类。实现方式就是上面类图中所描绘的。
下面我简单实现了一个自己功能的装饰流,
CharFilterInputStream类就是我们自己实现的,主要功能是过滤特殊字符的输入流,来看一下这个类的代码
下面是测试类:
分析一下各个组件:
Component(抽象组件角色):-被装饰对象的统一接口
ConcreteComponent(具体组件角色):-被装饰者
Decorator(抽象装饰器):-维持一个指向构件Component对象的实例
ConcreteDecorator(具体装饰器角色): -添加职责
其实这样看还是很抽象的,下面就借用JDK中的关于这个模式的应用,在Java I/O中就应用了装饰者设计模式,来看一下类图结构。
可以看到输入流有一个共同的基类,就是InputStream这个类在这个模式中扮演了Component的角色。
来看一下一个简化图吧~
可以看到这个FilterInputStream的类是非常重要的,下面是部分代码
public class FilterInputStream extends InputStream { /** * The input stream to be filtered. */ protected volatile InputStream in; /** * Creates a <code>FilterInputStream</code> * by assigning the argument <code>in</code> * to the field <code>this.in</code> so as * to remember it for later use. * * @param in the underlying input stream, or <code>null</code> if * this instance is to be created without an underlying stream. */ protected FilterInputStream(InputStream in) { this.in = in; }
可以看到这个类继承了一个InputStream,还聚合了一个InputStream,他的构造方法会传入一个InputStream这个类的作用就是装饰传来的输入流,看类的结构可以看出来继承FilterInputStream的类都是装饰类,他们数据的来源的别的输入流。
其实整个装饰者的思想就是用一些小部件来装饰一样东西,在生活中非常常见,比如说买咖啡的时候,一般先是一个普通的咖啡,你可以选择向里面添加糖或者牛奶或者冰块或者一些其他的东西,如果我们在设计一群这样类的时候采用继承的方式,每添加一个配料都要添加无数个种类的类,这样简直的类爆炸,所以我们会采用装饰者设计模式,用配料去装饰基类。实现方式就是上面类图中所描绘的。
下面我简单实现了一个自己功能的装饰流,
CharFilterInputStream类就是我们自己实现的,主要功能是过滤特殊字符的输入流,来看一下这个类的代码
package com.ls; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; /** * 过滤特殊字符的输入流,默认过滤数字 * @author LiuShuai * */ public class CharFilterInputStream extends FilterInputStream { //默认过滤的字符串 private static final char[] DEFAULT_CHARS = {'1','2','3','4','5','6','7','8','9','0'}; //过滤的字符串 private static char[] filterChars = null; public CharFilterInputStream(InputStream in) { this(in, DEFAULT_CHARS); } public CharFilterInputStream(InputStream in,char[] cs){ super(in); filterChars = cs; } @Override public int read(byte[] b, int off, int len) throws IOException { if (b == null) { throw new NullPointerException(); } else if (off < 0 || len < 0 || len > b.length - off) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0; } int n = 0; int c = read(); if (c == -1) { return -1; } b[off] = (byte)c; if (filterChar((char)c)) { n++; } int i = 1; try { for (; i < len ; i++) { c = read(); if (c == -1) { break; } if (filterChar((char)c)) { n++; } b[off + i] = (byte)c; } } catch (IOException ee) { } byte[] bs = new byte ; n=0; //这里进行字符串的过滤 for (int j = 0; j < b.length; j++) { byte d = b[j]; if (filterChar((char)d)) { bs[n++] = d; } } //这里是把过滤的字符串变成空格,而且把中间的空格去掉,其实是移到了最后面 for (int j = 0; j < b.length; j++) { if (j<bs.length) { b[j] = bs[j]; }else { b[j] = ' '; } } return i; } /** * 过滤某个字符 * @param c * @return */ private boolean filterChar(char c){ boolean flag = false; for(char c1 : filterChars){ if (c1 == (char)c) { flag = true; break; } } return flag; } }
下面是测试类:
public class Test { public static void main(String[] args) { try { Scanner scanner = new Scanner(System.in); String input = scanner.nextLine(); CharFilterInputStream charFilterInputStream = new CharFilterInputStream(new StringBufferInputStream(input)); BufferedReader reader = new BufferedReader(new InputStreamReader(charFilterInputStream)); System.out.println(reader.readLine()); } catch (Exception e) { e.printStackTrace(); } } } 运行结果:
相关文章推荐
- java 连接mysql数据库 并进行操作
- webService学习1:myeclipse解析wsdl
- Java笔记(七)多线程
- Java笔记(六) 对象群体的组织
- Java笔记(五) 输入输出
- Java练习:简单粗暴法选择排序
- Java基础1--变量与常量--imooc
- Java笔记(四) 接口与多态
- Java多线程基础知识疑难点
- 收集的一些常用java正则表达式
- Java笔记(三)类的重用
- 解决Eclipse导入项目:No projects are found to import
- JavaBean 的小知识点
- Java设计模式之工厂方法模式
- Java笔记(二)类的方法
- leetcode-java-26. Remove Duplicates from Sorted Array
- 给Java说句公道话-王垠
- Java笔记(一)类与对象的基本概念
- leetcode-java-20. Valid Parentheses
- myeclipse10.7.1无法打war包 提示:securecrt alert:integrity check error