Decorator Pattern(装饰者模式)

来源:互联网 发布:a6v5企业版软件下载 编辑:程序博客网 时间:2024/05/06 16:28
  从2016.11月工作以来很少有时间和心情认真写几篇博客了,以后还是应该回归自己这个明净的世界。

什么时候忘记适用性了 优缺点了 点它:装饰模式–百科
讲真,这个东西不是说抄一遍就能get的技能,要不重构一下自己的code基本没可能。


先理解一下工作原理

我们现在生活中理解一下Decorator Pattern.外国人都拿咖啡举例子,国内就说要用买煎饼,当然我觉得后者靠谱。快上车,老司机带你卖波煎饼

  • 买煎饼这件事这个图基本可以概括了。这段代码建议脑补
    这里写图片描述

上定义

  • The Decorator Pattern attaches additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending funcitionality.
  • 首先我们应该知道的是 Decorator Pattern 所普遍具有的类图结构大致如下:
    这里写图片描述

源码类图

  • 把应用Decorator patternjava.io 包中相关 和InputStream 的内容捋一下。(当然本包中不只有InputStream使用了 Decorator Pattern)

    1. 巴一眼UML:
      这里写图片描述
    2. 以上类图的内在逻辑
      这里写图片描述

    3. 小结:在学习设计模式之前我们看到这样的代码,除非有十个八个相同结构的代码供我们查看,否则我们是不能清晰的理出这其中的逻辑的。这也从侧面印证了 “设计模式是思维的复用”

从真实代码的角度更深入的理解这一设计(思维)模式

感觉有点力不从心,这更说明总结记录的重要性,这点知识掌握的还不够完全呢。(废话少说)

上干货:FilterInputStream概括性的介绍,再加上煎饼我们基本把这个事给理解了。

  1. InputStream
    这里写图片描述
  2. FileInputStream
    这里写图片描述
    关于以上两个图我只是想说用面向接口的思维理解这个抽象方法和这个子类。
    当然子类FileInputStream已经具体实现了InputStream中的read()方法,实现方式是通过JNI调用本地接口。这个本地接口的功能就是到物理存储设备上把二进制数据拿到内存中。
class FileInputStream extends InputStream{    //……    /**     * Reads a byte of data from this input stream. This method blocks if no input is yet available.     *      * @return     the next byte of data, or <code>-1</code> if the end of the file is reached.     * @exception  IOException  if an I/O error occurs.     */    public int read() throws IOException {        return read0();    }    private native int read0() throws IOException;    //……}

就像你看到的read()每次只能读取一个字节,我们知道从物理设备上读取数据相对于从内存读取要更加耗费时间,所以这里每次读取一个字节使我们不能接受的。当然 I/O 维护者和我们有同样的顾虑。

所以我们也听说了 BufferInputStream 这个带缓冲区的InputStream,它具有InputStream的特性,同时比单纯的InputStream多了一个对缓冲区的维护。[是不是有点 Decorator的意思]
1. BufferInputStream
这里写图片描述
你或许觉的我说的不对,因为InputStream中本来就有一个方法,可以完成一次读取若干:

    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 c = read();        if (c == -1) {            return -1;        }        b[off] = (byte)c;        int i = 1;        try {            for (; i < len ; i++) {                c = read();                if (c == -1) {                    break;                }                b[off + i] = (byte)c;            }        } catch (IOException ee) {        }        return i;    }

但是你要知道如果有人把这个你所谓的“若干”给你封装好,而不用你自己维护,这岂不是很方便?[这个人就是Decorator]
我们来看下BufferedInputStream中对于read() 方法的封装:

class BufferedInputStream extends FilterInputStream {    private static int DEFAULT_BUFFER_SIZE = 8192;//byte[DEFAULT_BUFFER_SIZE]-->8K    //……        public synchronized int read() throws IOException {        if (pos >= count) {            fill();            if (pos >= count)                return -1;        }        return getBufIfOpen()[pos++] & 0xff;    }    private void fill() throws IOException {        //……        count = pos;        int n = getInIfOpen().read(buffer, pos, buffer.length - pos);        if (n > 0)            count = n + pos;    }    private InputStream getInIfOpen() throws IOException {        InputStream input = in;//这个in使我们使用构造方法获取本类对象的时候得到的一个InputStream类型参数        if (input == null)            throw new IOException("Stream closed");        return input;    }        //……}

说白了这段代码做的事情就是把InputStream中的内容读取到一个java封装好的数据缓冲区(byte数组)中去,并且返回一个值,如果我们是第一次调用这个read()方法返回值就是InputStream中的数据中的第一个字节数据的16进制形式数字。
我还没搞明白:为什么 [value & 0xff] 是把value转换为16进制的形式

参考:

  1. 《Head First Design Patterns》——以上内容大部分来自这里。
  2. FilterInputStream概括性的介绍
  3. 这里有煎饼的栗子蛮不错的
  4. 装饰模式–百科
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 手机计算机桌面找不到怎么办 手机忘记开锁密码怎么办 电脑没网感叹号怎么办 本地连接2没有了怎么办 电脑上找不到本地连接怎么办 网络无访问权限怎么办 电脑无网络访问怎么办 xp连不上网怎么办 xp系统本地连接不见了怎么办 电脑xp系统本地连接怎么办 xp系统本地连接失败怎么办 xp系统找不到本地连接怎么办 台式电脑连不上网络怎么办 win7局域网要密码怎么办 xp网络不能上网怎么办 台式电脑连宽带怎么办 win7宽带813错误怎么办 电脑不显示本地连接怎么办 w7宽带连接不了怎么办 网络接收器坏了怎么办 电脑网页打开慢怎么办 win10无法添加打印机怎么办 2018杭州禁摩怎么办 中山个人怎么办社保卡 昆山房产证丢了怎么办 于一机交宽带费怎么办 租房子的怎么办宽带 乐才注册不了怎么办 分期乐登录不了怎么办 股票忘记交易密码怎么办 信用卡交易密码忘记怎么办 乐购超市怎么办会员 手机分期付款0首付怎么办 首付手机违约了怎么办 买了假东西怎么办 pk10滚雪球挂了怎么办 好彩投彩票闪退怎么办 yeezy买小了怎么办 yeezy斑马变黄了怎么办 yeezy买大了怎么办 聚宝商城被骗怎么办