0x00.概括
看装饰模式看了实在是有点久。
下面是从《head first design patterns》原文对Decorator pattern的概括1.Decorators have the same supertype as the objects they decorate.
2.You can use one or more decorators to wrap an object.
3.Given that the decorator has the same supertype as the object it decorates, we can pass
around a decorated object in place of the original (wrapped) object.
4.The decorator adds its own behavior either before and/or after delegating to the object it
decorates to do the rest of the job.
5.Objects can be decorated at any time, so we can decorate objects dynamically at runtime
with as many decorators as we like.
我百度看的博客,还是我自己买的《大话设计模式》的书,还是电子版的《head first design patterns》
顺便提一下发现一个有趣的东西,《大话设计模式》中内容很大程度程度上是参chao考xi了《head first design patterns》
这本书的内容的。然后国内的很大一部分的博客呢就是将《大话设计模式》或者是《head first design patterns》中的例子
、内容抄下来加一点或者减一点东西然后就标上原创,我看了极客学院上唯一一个讲装饰模式的视频就是按《head first des
ign patterns》的内容读了一遍,我就不明白了做了那么多年的开发就没有自己一点独立的见解东西吗。这个看了他的博客然
后写一遍,那个看了这个博客然后又写了一遍。导致内容全部都差不多,例子也是,真是服了。当然指的不是全部,还是有一
些写的有自己独立见解的。我只是对这些乱象说下,我自己水平也不咋地。
我看过写的例子大部分有咖啡店版,穿衣服版。
咖啡店版的都是Component有一个cost()接口,ConcreteComponent和Decorator都去实现这个接口,你用Decorator去装饰
ConcreteComponent的时候就你就可以修改cost的返回值了。
穿衣服的也是Component有一个show()接口,做法和上面一样,只要你用什么Decorator去修饰他,show()的时候就可以体
现出你到底穿了什么衣服。
就不贴代码了,博客上这两种例子随便一搜都能找到。
0X01
网上都是Java中的IO就是采用设计模式设计的。我就看了下,总结下吧。
1.结构图
这是java中IO继承关系图,其实省略了一些的,看源码可以看出来。这个结构和装饰者模式的结构差不多
2.Component类之InputStream
InputStream就是Component有一些接口贴下API中的文档,其实也就是这些如果你要具体的话可以自己翻看源码。
我也就举一个重要的接口read(),别的read都是靠这个实现的
public abstract int read() throws IOException;
这是源码中写的,是一个抽象方法,并且会抛出异常。
3.ConcreteComponent类之FileInputStream
下面看他的子类,被装饰者FileInputStream中是怎么实现read()的
public int read() throws IOException { return read0(); } private native int read0() throws IOException;
通过jni实现没有具体的代码。但是就是在这边实现了。
4.Decorator类之FilterInputStream
我们看下在FileterInputStream中read是一个什么情况这边的read就是调用传进来的InputStream的read来实现的,和装饰模式一样。protected FilterInputStream(InputStream in) { this.in = in; } public int read() throws IOException { return in.read(); }
其实到这边FilerInputStream中的接口和InputStream是一样的,而且都是调用传入的InputStream的方法。
5.ConcreteDecorator类之BufferedInputStream
我们看下具体的Decorator的BufferedInputStream,不知道BufferedInputStream自行百度然我们看下方法先判断缓冲区是否已经读完了,读完了调用fill()去开IO填满缓冲区,返回。这个装饰类给前面的private InputStream getInIfOpen() throws IOException { InputStream input = in; if (input == null) throw new IOException("Stream closed"); return input; } public synchronized int read() throws IOException { if (pos >= count) { fill(); if (pos >= count) return -1; } return getBufIfOpen()[pos++] & 0xff; } private byte[] getBufIfOpen() throws IOException { byte[] buffer = buf; if (buffer == null) throw new IOException("Stream closed"); return buffer; } <span style="white-space:pre"> </span>private void fill() throws IOException { byte[] buffer = getBufIfOpen(); /** *省略一大段代码!!! **/ int n = getInIfOpen().read(buffer, pos, buffer.length - pos); if (n > 0) count = n + pos; }
read()方法上增加了一个缓冲区的功能,可以优化在读取大量的字符数组的时候适用。
0X02.总结
写完这篇总结,自己也感悟良多,个人感悟,如有错误请在评论区骂我。
装饰模式运用场景是你有一个主功能,你这个功能可以动态的添加一些奇奇怪怪的功能,这些功能在特定的场合可能可以
用上,也可能没什么卵用。并且奇奇怪怪的功能可以嵌套的添加,这意味你添加上奇怪功能后你的使用还是和以前一样。
设计模式真的是非常的神奇的一个东西啊!!棒棒哒
0x03.附录
在AndroidStudio下写了一个装饰模式的样例,因为喜欢英雄联盟,所以实例是一个英雄装备武器的实例,带来攻击不同的效果,看起来好像和衣服的差不多。