科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道Java API设计指南4

Java API设计指南4

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

Java API设计指南

作者:王磊 来源:IT专家网 2008年6月5日

关键字: 指南 设计 API java

  • 评论
  • 分享微博
  • 分享邮件
构造函数的优点就在于子类可以调用父类的构造函数。static函数则是可以返回具体类的子类实现。

  《Effective Java》书中第十条则给出了clone()带来的痛苦。

  (译注:个人不同意这个观点,我觉得clone非常有用,特别是在多线程的处理中,我会再撰写关于clone方面的文章,而且前面提到的缺点也都是可以通过一些设计上的技巧来改正。)

  异常应该尽可能的是unchecked类型的,《Effective Java》书中第41条则给出了详细的说明。如果当前API只能抛出异常,而且开发人员可以对异常进行处理,如释放资源,就可以使用Checked异常。因此所谓的Checked异常就是API内部与外部开发人员进行问题交互的一种方式。如网络异常,文件异常或者是UI异常等信息。如果是输入参数不合法,或者是一个对象的状态不正确,就应该使用Unchecked异常。

  一个类如果不是抽象类,就应当是final类不可被继承。《Effective Java》第15章给出了足够的理由,同时也建议每个方法在默认情况下都应该是final(目前Java正好相反)(译注:这点我也赞成,觉得方法默认为final更好,但是目前Java发展到当前情况下,已经不可能大规模的更改了,不能不说是Java语言的一个遗憾之处,C#这一点处理的更好,默认为final,后面的留言也提到这个了)。如果一个方法可以被覆盖,一定要在文档中清楚的描述这个方法被覆盖后带来的后果,最好还能提供一些例子程序进行演示以避免开发人员误用。

  总结

  •   设计需要演化,否则会降低它的价值。
  •   先保证API的正确性,在此基础上再追求简单和高效
  •   接口并不如想像中的那么有用。
  •   谨慎分包可以带来更多的价值。
  •   不要忘记阅读《Effective Java》(译注:难道作者和Josh Bloch's有分赃协议不成。)

  以下是当前文章一些讨论的意见(因为比较多,所以我没有全部翻译,但是国外技术论坛上的一些讨论,其价值往往比文章的价值更大,建议可以自行阅读一下。):

  Gregor Zeitlinger写道:

  如果使用作者给出的API标准,C#很多方面是不是做的更好呢。

  C#的方法在默认情况是final的,不可被重载。(译注:个人意见,在这一点上C#比Java更好,而且,参数默认就应该是final,因为java参数是传值的,所以也不应该改变)。

  C#只有unchecked exception(新的规范中又重新提出了checked exception)。(译注:个人认为checked exception的价值还是很大的,不过在Java中,有些被误用了)。

Eamonn McManus 写道:

  我个人不认为让大部分方法都成为final是一个好的设计方案。根据我个人的经验,这种处理方式将会严重的降低代码的复用度。

  如果更极端的说一下:也许不应该有private方法,所以的方法都应该是protected甚至是public,这样可以有益于复用度。当然这样处理带来的一个明显缺点就是没有人知道哪个方法可以被安全的复写(overrid)。

  (译注:这也太极端了,如果这样,一个API的规模恐怕会是原来的10倍以上,不要说复用,恐怕怎么用我都不知道了,想想一下一个1000个类,10000个public方法的API包吧)。

  Gregor Zeitlinger写道:

  在什么情况下我们要同时提供接口和抽象类呢。举个例子,Java的集合框架中提供了List这个接口和AbstractList这个抽象类。

  接口的好处在于

  •   多继承
  •   其实现子类可以有最大的灵活性
  •   能够将API的描述信息与其实现彻底分离

  类的好处在于:

  •   提供通用的方法,避免重复代码
  •   能够支持接口的演化

  Eamonn McManus 写道:

  Bloch在《Effective Java》中强烈建议在提供一个接口的同时,尽量提供一个实现了该接口的抽象基类。这话在Java集合框架的设计体现的淋漓尽至,他老兄就是Collection框架的主设计师。这个设计的模式在许多场景中都是非常有用的,不过也不要把它当作金科玉律,一言而敝之:不要为模式而模式。

  即使你使用了接口+基类的方式,也不能保证你API的演化,除非你只在基类中添加方法,而不在接口中添加方法,这种情况带来的坏处就是混乱,如果一个类想调用这个新添加的方法,因为接口中没有添加这个方法,所以通过接口是无法调用的,那么只能将它强行转型,然后再调用,但有时候又很难确认你的强行转型是正确,糟糕的ClassCastException又出现了。除非你能保证所有的子类都继承这个基类,不过这种情况和中彩票的机会相差不多吧。

  现在来谈一下unchecked exceptions和C#的问题,许多人都觉得在Java中Checked exceptions并不是一个缺陷,或者说它不是一个严重的问题。但我不这样认为:象IOException这种异常,应该是Checked Exception,以便由编译器来提醒程序员时要正确处理资源问题,这是一件好事,但是在Java中,有大量不必要的异常成为Checked Exception,这些Checked Exception却给程序员带来了许多麻烦。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章