1. 装饰者模式的详解
装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性
的替代方案。
装饰者模式设计类之间的关系:


中Component是一个超类,ConcreteComponen是被装饰者,Decorator是装饰者,装饰者和被装饰者有共同的超类
Component,但是此时我们发现Decorator和Component还有另外一条线,这条线表示Decorator还要组合
Component。
在我看来装饰的模式中这几个类的主要作用如下:
首先我们看一个这样的现象(这个是我在网上看到的例子,我把它引入进来主要是方便谈谈我的理解)
现象描述:

果说继承里的超类是一个模具(Component),做出各种各样的稍有不同的子类成品
(ConcreteComponen,ConcreteDecoratorA,ConcreteDecoratorB)来满足各种各样的功能。那么把装饰
模式比作的一条生产线吧,一个产品(ConcreteComponen)传过来,在各道工序不断地给它加上新的功能,把它一步步按照顺序包装成一个全新的
产品(Concrete DecoratorA,Concrete
DecoratorB)。记住,这条生产线可能是无限长的,这种包装也可以是无限添加的。
我的理解
1.
Component是超类,他出现的意义是什么呢?照理说Decorator直接去组合ConcreteComponent,就可以去加强
ConcreteComponent的行为,成而加工出一个不通的子类成品。但是可能有这样一种情况,ConcreteComponent的平级的区域内
还有ConcreteComponent1,ConcreteComponent2……这样要为每一个ConcreteComponent都去写一个
Decorator吗?这样显然不可能。所以抽象出Component的一个好处就是让ConcreteComponent和Decorator彼此解
耦。Decorator只要得到Component对象的引用即可。
2.
Decorator是装饰者,而真正装饰的过程是在Decorator的子类ConcreteDecoratorA和
ConcreteDecoratorB中完成的,他们使用不同的装饰方法,作出了不同的子类成品。Decorator的作用只是告诉大家,我要去装饰
ConcreteComponent,或许还会提供一些用这个装饰者去装饰的而形成的成品共用的特性和功能。
3. 装饰者永远是装饰者,但装饰者装饰出来的成品也有可能会变成被装饰者。即ConcreteDecoratorA和ConcreteDecoratorB有一天也会变到ConcreteComponen的地位。
只不过这个时候在ConcreteDecoratorA的旁边可能会出现一个类似于Decorator的装饰者DecoratorA,它同样要继承并组合超类Component。目的是相同的:解耦,让一个装饰者不必为一个被装饰者而存在
这时候的装饰者模式的结构图变成:


上图说明一个道理,如果条件容许的话Decorator和DecoratorA的位置是可以互相交换的。这就像冲一杯带糖的奶粉,Decorator表示
放糖,DecoratorA表示放奶粉,其实是先放糖还是先放奶粉,最终都能得到ConcreteDecoratorAA(一杯带糖的奶粉)。当然这是在
条件容许的情况下,在有些生产环境中,制做工序(装饰的先后)是不能乱的。

2. 装饰者模式在JAVA IO中的应用
先给出Java IO包中主要类的关系:
java
IO包中有四大等级结构InputStream,outputStream,
InputStreamReader,outputStreamReader。InputStream和OutputStream处理8位字节流数据,
Reader和Writer处理16位的字符流数据。InputStream和Reader处理输入,
OutputStream和Writer处理输出。各个体系内部用到的都是装饰者模式,而InputStream和InputStreamReader之
间,outputStream和outputStreamReader之间用的是适配器模式
下面主要以InputStream和InputStreamReader为例详解
1. 从装饰者模式看InputStream结构

InputStream的类图关系
class java.lang.Object
|
|—class java.io.InputStream //输入流,字节形式,为以下的基类
| |
| |——ByteArrayInputStream //从字节数组中读取
| |
| |——FileInputStream //从文件中读取数据
| |
| |—— FilterInputStream //过滤流的基类,
| | | // 过滤可以了解为各种处理技术的形象称呼
| | |
| | |——BufferedInputStream //缓冲技术,
| | | // 数据来自底层输入流
| | |
| | |——DataInputStream //可读java数据类型
| | |
| | |——PushbackInputStream //缓冲技术,
| | | // 数据来自任意输入流
| | |
| | |——java.util.zip.GZIPInputStream
| | | //不是java.io包中的流。压缩技术
| | |
| | |——java.security.DigestInputStream
| | | //不是java.io包中的流。处理流的摘要
| | |
| |—— .......
从图中可以看出,InputStream就是装饰者模式中的超类(Component),ByteArrayInputStream,FileInputStream相当于被装饰者(ConcreteComponent),这些类都提供了最基本的字节读取功能。
而另外一个和这两个类是同一级的类FilterInputStream即是装饰者(Decorator),BufferedInputStream,DataInputStream,PushbackInputStream…这些都是被装饰者装饰后形成的成品。
根据装饰者模式的特点,我们可以总结出这些IO流的使用方法:
File file = new File ("hello.txt");
FileInputStream in=new FileInputStream(file);
BufferedInputStream inBuffered=new BufferedInputStream (in);
这里BufferedInputStream主要是提供了缓存机制,先读入一个byte[],等count到达缓存Byte[]的大小的时候,再一次读入。
当然你也可以写成BufferedInputStream inBuffered =
new BufferedInputStream (new FileInputStream(new File ("hello.txt")));
从使用的角度来看装饰者模式,可以看出它的一个缺点:装饰者模式的实现对于使用者是透明的,当使用者不熟悉你的实现的时,就很难理解。

同理你可以学习一下另外一个结构outputStream

2. 适配器模式看InputStreamReader
适配器模式比较简单就不多讲了,主要是解决了java无法多继承的问题,下面大概讲一下IO包中是怎么用这个模式的,用它来做什么?
InputStreamReader
和InputStream的功能的不同点在于InputStream是以二进制输入 / 输出, I/O
速度快且效率高,由于读到的是字节,也就不存在乱码问题,平台移植性好。但是它的 read
()方法读到的是一个字节,很不利于人们阅读。InputStreamReader类将字节转换为字符。
你可以在构造器中指定编码的方式,如果不指定的话将采用底层操作系统的默认编码方式。
Java.io.Reader类提供了要求了继承这个类的所有类必须提供
   /**
     * Reads characters into a portion of an array.  This method will block
     * until some input is available, an I/O error occurs, or the end of the
     * stream is reached.
     *
     * @param      cbuf  Destination buffer
     * @param      off   Offset at which to start storing characters
     * @param      len   Maximum number of characters to read
     *
     * @return     The number of characters read, or -1 if the end of the
     *             stream has been reached
     *
     * @exception  IOException  If an I/O error occurs
     */
abstract public int read(char cbuf[], int off, int len) throws IOException;
代码注释理解:读出来的形式必须是字符,而不是字节了,InputStreamReader继承于Reader,即具备了读出字符的功能,而把什么读成字节的功能就要InputStreamReader去适配了,InputStreamReader的构造函数是这样的:

/**
     * Creates an InputStreamReader that uses the named charset.
     *
     * @param  in
     *         An InputStream
     *
     * @param  charsetName
     *         The name of a supported
     *         {@link java.nio.charset.Charset </code>charset<code>}
     *
     * @exception  UnsupportedEncodingException
     *             If the named charset is not supported
     */
    public InputStreamReader(InputStream in, String charsetName)
        throws UnsupportedEncodingException
    {
super(in);
if (charsetName == null)
    throw new NullPointerException("charsetName");
sd = StreamDecoder.forInputStreamReader(in, this, charsetName);
    }
用的是InputStream去适配InputReader。

3. 浅谈Reader体系
Reader体系中同样用到的是装饰者模式,但是有一点不同,Reader体系中的FilterRead类和InputStream体系中的FilterInputStream的功能不同,它不再是装饰者。
这一点可以从BufferReader和BufferStreamReader的实现不同可以看出
bufferReader:public class BufferedReader extends Reader
BufferedInputStream:public class BufferedInputStream extends FilterInputStream
但模式还是相同的。在Reader我没找到FilterInputStream类似作用的东西
下面看看Reader IO的使用方法
1. File file = new File ("hello.txt");  
2. FileInputStream in=new FileInputStream(file);
3. InputStreamReader inReader=new InputStreamReader(in);
4. BufferedReader bufReader=new BufferedReader(inReader);
可以看出步骤2到3使用的是适配器模式,而3到4使用的是装饰者模式

好了,以上就是我学习设计模式和java IO的心得,自己也是初学者,希望对同样这块不太了解的人有所帮助,有什么意见大家可以提出。

从装饰者模式的理解说JAVA的IO包的更多相关文章

  1. 由装饰者模式来深入理解Java I/O整体框架

    前言 Java里面的I/O这一部分看过很多遍,每次看完之后特别混乱,又是输入流,又是输出流,又是字符流,又是字节流,还有什么过滤流,缓冲流.每次看得我如入云里雾里,直到后面看了设计模式这一块,才算真正 ...

  2. (十)装饰器模式详解(与IO不解的情缘)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. LZ到目前已经写了九个设计模 ...

  3. 涉及模式之 装饰器模式详解(与IO不解的情缘)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. LZ到目前已经写了九个设计模 ...

  4. Java 装饰器模式详解

    转载请注明出处:http://blog.csdn.net/zhaoyanjun6/article/details/56488020 前言 在上面的几篇文章中,着重介绍了Java 中常见的 IO 相关知 ...

  5. Java装饰者模式(Decorator)

    一.定义 装饰模式的设计理念主要是以对客户端透明的方式动态扩展对象的功能,是继承关系的一个替代(继承会产生大量的子类,而且代码有冗余).装饰模式可以在不创造更多子类的情况下,将对象的功能加以扩展.装饰 ...

  6. 从源码角度理解Java设计模式——装饰者模式

    一.饰器者模式介绍 装饰者模式定义:在不改变原有对象的基础上附加功能,相比生成子类更灵活. 适用场景:动态的给一个对象添加或者撤销功能. 优点:可以不改变原有对象的情况下动态扩展功能,可以使扩展的多个 ...

  7. 【设计模式】装饰者模式(DecoratorMode0

    From: https://liudongdong1.github.io/ 装饰者模式(Decorator Pattern):动态地给一个对象增加一些额外的职责,增加对象功能来说,装饰模式比生成子类实 ...

  8. Java 新IO

       NIO提供全新的底层I/O模型.与最初的java.io包中面向流(stream-oriented)概念不同,NIO采用了面向块的概念(block-oriented).在尽可能的情况下,I/O的操 ...

  9. java的io库用到的装饰模式是如何体现的?

    概论 java的io包下大概有85个类,真复杂.其实不然这些类又可以分为以下四个部分. 输入流                输出流 字节流         InputStream          ...

随机推荐

  1. 海面波浪模拟 MATLAB

    数学建模美赛集训的时候要用到一个海面模拟,分享一下海面模拟的MATLAB代码 先贴一下结果图: 下面是源代码~~~ function waterwave n = 64; % grid size g = ...

  2. Angular5学习笔记 路由配置

    因为angular-cli脚手架的关系,所以配置路由可以通过命令行来创建路由文件 原本创建一个angular项目的命令是ng new 项目名,就可以了,但这样创建出来的项目是没有路由文件的. 如果需要 ...

  3. 20155211 2016-2017-2 《Java程序设计》第四周学习总结

    20155211 2016-2017-2 <Java程序设计>第四周学习总结 教材学习内容总结 这周的内容感觉较上周相比难度增加 教材学习中的问题和解决过程 刚开始学习第六章的时候的时候敲 ...

  4. itop4412学习-上层应用多任务开发

    1. 首先搭建虚拟机VMWARE12.0+UBUNTU16.04,不过报错了,说是要关闭计算机(非重启)-- 进入BIOS -- 设置BIOS的虚拟化(不打开,默认是工作在32位模式的,virtual ...

  5. LAUNCHXL-28379D入门学习-第一篇

    1. 首先安装controlSUITE或者C2000ware软件,TI官网下载,安装后包括C2000的函数库和例程之类的,还可以和CCS搭配使用.controlSUITE安装完之后大约4个G,所以我安 ...

  6. 【MySQL安装】MySQL5.6在centos6.4上的安装

    卸载原来安装的mysql 安装从官网下载的mysql rpm包 发现有依赖,需要先安装libaio包和libnuma包 再装mysql就可以了 安装客户端 安装完成后,启动mysql 但是发现用没有m ...

  7. Tp框架之命名空间

    命名空间,相当于虚拟目录 实现自动加载类的机制 初始命名空间:Library文件夹 初始命名空间下面有很多根命名空间: 1.Library里面的文件夹 2.APP的模块文件夹 在tp框架中,只有这两个 ...

  8. PHP Redis 缓存数据

    // 注:只是在此做下记录,有兴趣的可以参考,不做实际教程文档// 配置文件define('CONFIG', [ 'redis-server' => '127.0.0.1', 'redis-po ...

  9. 「Leetcode」975. Odd Even Jump(Java)

    分析 注意到跳跃的方向是一致的,所以我们需要维护一个数接下来跳到哪里去的问题.换句话说,就是对于一个数\(A_i\),比它大的最小值\(A_j\)是谁?或者反过来. 这里有两种方案,一种是单调栈,简单 ...

  10. RyuBook1.0案例三:REST Linkage

    REST Linkage 该小结主要介绍如何添加一个REST Link 函数 RYU本身提供了一个类似WSGI的web服务器功能.借助这个功能,我们可以创建一个REST API. 基于创建的REST ...