ObjectInputStream不应该扩展FilterInputStream吗?

时间:2010-05-24 12:37:27

标签: java design-patterns java-io

块引用来自Java Docs -

  

FilterInputStream包含一些   其他输入流,它用作   它可能是其基本数据来源   沿途改变数据或   提供额外的功能。

     

DataInputStream允许   应用程序读取原始Java数据   来自基础输入流的类型   与机器无关的方式。

DataInputStream因此延伸FilterInputStream

  

ObjectInputStream反序列化   以前的原始数据和对象   使用ObjectOutputStream编写。

但是,出于某种原因,ObjectInputStream不会扩展FilterInputStream,即使它也是从底层输入流中读取对象(这次而不是基本类型)。这是相关课程的分支。

alt text

是否有相同的设计推理?

3 个答案:

答案 0 :(得分:3)

明智的问题。考虑到这一点,我认为Object*Stream可以设计为扩展Filter*Stream(同样适用于输出或输入)。为什么没有这样做?也许是因为:

  1. 没有任何实际好处。正如Maciej所解释的那样,除了一些不重要的组织类之外,Filter*Stream的要点是提供一些常见的默认(并且相当简单)实现具有该模式的类(从一些底层流读取/写入,最终转换流),由其他类(来自Java API或用户)扩展。但Filter*Stream接口无关:例如,您几乎永远不会找到或实现一些需要Filter*Stream作为参数的方法。因此,当有替代方法时,让类继承*StreamFilter*Stream的决定主要是实现决策;班上的用户基本上不在乎。

  2. ObjectOutputStream的设计者决定给那些愿意扩展课程的人提供额外的灵活性,完全重新实现它,给予额外的empty constructor(没有潜在的OuputStream) 。这个特性(我认为相当罕见)将类(概念上和实现方式)放在Filter*Stream类之间。再次,这似乎并不确定。

答案 1 :(得分:2)

之间有区别:

  • 逻辑继承(共享界面)
  • 在类之间共享代码时的'代码'继承

逻辑上LinkedList不是AbstractList,因为它不是抽象的。但是从代码的角度来看,分享List方法的一些实现是有益的,因为它们可以用其他方法实现,通常具有相同的效率(例如isEmpty可以实现为{{ 1}})。

某些平台,例如GObject(或者某些扩展Haskell - 虽然它不是OO语言,并且很多东西完全不同)但是在接口中默认实现方法是定义它。

然而,Java不是使用size() == 0类来重用代码的情况。 Abstract*并不是定义输出是在某处发送的(因为Java I / O的重点是产生者/接收者不关心),但它用于重用公共代码。

答案 2 :(得分:1)

我想ObjectInputStream必须覆盖FilterInputStream的每个方法。

当你这样做时,没有必要保持这种关系。

重要的是:ObjectInputStream IS 一个InputStream(除了其他方法之外,你仍然可以将原始数据写入它)并且那个关系就在那里。