Java设计模式--装饰模式

定义

  • 装饰者模式动态的将功能加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

几个要点

  • 装饰者和被装饰者有相同的父类
  • 你可以用一个或多个装饰者装饰一个对象。
  • 既然装饰者和被装饰者有相同的父类,所以在任何需要原始对象(被包装对象)的场合,可以用装饰过的对象代替它。
  • 装饰者可以在所委托被装饰者的行为之前与/或之后,加上自己的行为,以达到特定的目的
  • 对象可以在任何时候被装饰,所以可以在运行时动态地、不限量地用你喜欢的装饰者装饰对象

看看Java I/O中的InputStream怎么用的装饰者模式(io包中应用大量的装饰者模式,以InputStream为例)

InputStream

/**
 * This abstract class is the superclass of all classes representing
 * an input stream of bytes.
 *
 * <p> Applications that need to define a subclass of <code>InputStream</code>
 * must always provide a method that returns the next byte of input.
public abstract class InputStream implements Closeable {
        ...
}

InputStream 是所有字节输入流的父类,继承InputStream的子类都要实现返回下一个输入字节的方法(read()).

FileInputStream

/**
 * A <code>FileInputStream</code> obtains input bytes
 * from a file in a file system. What files
 * are  available depends on the host environment.
 *
 * <p><code>FileInputStream</code> is meant for reading streams of raw bytes
 * such as image data. For reading streams of characters, consider using
 * <code>FileReader</code>.
public class FileInputStream extends InputStream {
    ...
}

FileInputStream主要功能是从文件中读入字节

BufferedInputStream

/**
 * A <code>BufferedInputStream</code> adds
 * functionality to another input stream-namely,
 * the ability to buffer the input and to
 * support the <code>mark</code> and <code>reset</code>
 * methods. When  the <code>BufferedInputStream</code>
 * is created, an internal buffer array is
 * created. As bytes  from the stream are read
 * or skipped, the internal buffer is refilled
 * as necessary  from the contained input stream,
 * many bytes at a time. The <code>mark</code>
 * operation  remembers a point in the input
 * stream and the <code>reset</code> operation
 * causes all the  bytes read since the most
 * recent <code>mark</code> operation to be
 * reread before new bytes are  taken from
 * the contained input stream.
 */
public
class BufferedInputStream extends FilterInputStream {
    ...
}

BufferedInputStream给InputStream增加一个功能:利用缓存高效读入字节,支持标记和重置。

  • FileInputStream是InputStream的子类,继承之后针对文件读取添加功能,BufferedInputStream是FilterInputStream的子类,FilterInputStream继承了InputStream,所以BufferedInputStream同样是InputStream的子类,构造方法中需要传入一个InputStream。所以如何高效的读入文件就是这样了
public class IOTest {
    public static void main(String[] args) {
        File file = new File("test.txt");
        try {
            BufferedInputStream bi = new BufferedInputStream(new FileInputStream(file));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

}
  • 创建出来的FileInputStream作为被包装者传给BufferedInputStream,FileInputStream只负责读入文件,当想要提高效率的时候并没有在FileInputStream内部添加缓冲的方法,而是将起作为被装饰者传给BufferedInputStream,BufferedInputStream负责添加高效读入的功能,实现高效率读入文件.单一原则、开闭原则(对扩展开放,对修改关闭)体现的淋漓尽致!

结束语

仔细品味装饰者模式的要点,结合Java的IO操作就可以很好的理解装饰者模式了,最后附上一篇结合装饰者模式 优雅的为RecyclerView添加Header以及Footer的博文,加深理解。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 装饰模式的定义是:装饰模式又名包装(Wrapper)模式。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的...
    li_jun阅读 2,125评论 2 0
  • 装饰模式 1.定义: 动态的给一个对象添加一些额外的职责。就增加功能来讲,装饰模式比生成子类更为灵活。 2.使用场...
    TangBuzhi阅读 252评论 0 0
  • 1 场景问题# 1.1 复杂的奖金计算## 考虑这样一个实际应用:就是如何实现灵活的奖金计算。 奖金计算是相对复杂...
    七寸知架构阅读 4,062评论 4 67
  • 装饰模式用于在不改变原类的情况下,扩展一个类的功能,这种扩展是动态的,动态的为一个对象增加功能,而且还动态撤销功能...
    黑白咖阅读 225评论 0 0
  • 语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. ...
    JasonQiao阅读 594评论 0 0