V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
amiwrong123
V2EX  ›  Java

为什么 Java IO 体系中的装饰者模式中,一定用弄个 FilterInputStream 作为 DataInputStream, BufferedInputStream 的父类?

  •  
  •   amiwrong123 · 2020-01-18 12:47:15 +08:00 · 3903 次点击
    这是一个创建于 1557 天前的主题,其中的信息可能已经有所发展或是发生改变。

    直接让 BufferedInputStream 继承抽象类 InputStream,再令其构造器的实现为类似:

    class BufferedInputStream extends InputStream{
        protected volatile InputStream in;
        protected BufferedInputStream(InputStream in) {
        this.in = in;
        }
    

    这样不行吗

    或者说只是为了抽取处子类的公共部分吗

    8 条回复    2020-01-20 10:49:32 +08:00
    guyeu
        1
    guyeu  
       2020-01-18 14:23:07 +08:00
    FilterInputStream 是代理模式,DataInputStream 和 BufferedInputStream 都使用了代理这个特性。
    bagel
        2
    bagel  
       2020-01-18 14:44:31 +08:00   ❤️ 1
    这是 x 模式,那是 y 模式,中间还用到了 z 模式……这让我想起项飙吐槽西方人类学:一些人类学家说一些话,以便让别的人类学家有话可说。
    KunMinX
        3
    KunMinX  
       2020-01-18 15:26:24 +08:00 via iPhone
    okio 解君愁
    LowBCoder
        4
    LowBCoder  
       2020-01-18 16:48:34 +08:00
    @guyeu FilterInputStream 是装饰器模式。。。
    我个人的理解(有不对的地方请指出哈)是 FilterInputStream 这个的子类,是流读取的方法的抽象( Data 读取、缓存读取),InputStream 的子类是流类型的抽象(比如文件读取、字节读取),了解下装饰器模式你就会发现,装饰器模式的好处是在运行时扩充功能,所以 IO 用继承去处理流类型的抽象,然后用装饰器模式去处理流读取方法的抽象,如果全部用继承的话,流读取方法的抽象和流类型的抽象的组合就需要多一层继承关系去处理,会增加很多代码量,也不好拓展。
    guyeu
        5
    guyeu  
       2020-01-18 19:01:43 +08:00   ❤️ 2
    @LowBCoder #4 说 FilterInputStream 是 InputStream 的代理而不是装饰器的原因如下:
    1. FilterInputStream 并没有给 InputStream 扩展任何功能,只是持有了一个 InputStream 的实例,所有的操作都转交给持有的这个 InputStream 的实例去做;
    2. BufferedInputStream 和 BufferedInputStream 可以说是装饰器模式,都为 InputStream 增加了不属于它的特性;

    抽象出一个用于代理的实现类而不是把同样的方法按照挨个在 BufferedInputStream 和 BufferedInputStream 里实现一遍,最显而易见的原因就是为了使代码简介,使用到了代理这个特性,所以抽象出一个代理者。
    D3EP
        6
    D3EP  
       2020-01-19 14:30:02 +08:00
    FilterInputStream 类似于 Guava 中的 ForwardingXXX 类,比如 ForwardingQueue。
    主要是为了在添加新功能时,避免重写其它方法。
    代理模式和装饰器模式区分没那么严格,都是持有一个对象,然后添加一些功能。
    LowBCoder
        7
    LowBCoder  
       2020-01-20 10:47:21 +08:00
    @guyeu 受教了,感谢回复
    LowBCoder
        8
    LowBCoder  
       2020-01-20 10:49:32 +08:00
    @guyeu FilterInputStream 确实只是持有一个 InputStream 实例,这一块代码我刚才又去看了下,之前确实是自己没有结合代码理解透彻
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   956 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 21:20 · PVG 05:20 · LAX 14:20 · JFK 17:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.