科技行者

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

知识库

知识库 安全导航

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

Java API设计指南2

  • 扫一扫
    分享文章到微信

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

Java API设计指南

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

关键字: 指南 设计 API java

  • 评论
  • 分享微博
  • 分享邮件
就象业界游行的经验之谈--“不要使用3.0版本以下的软件”(译注:所以我总想把自己的软件直接发布为9.9。),同样的情况对API也是一样的,前几个版本的API往往包含有大量的错误,这些错误不应该被隐藏起来,因为纵然是冰山的底部,也终有浮出水面的一天。因此在正式发布API 1.0以前,请不要忘记提供若干个0.x版本。对于使用0.x版本的用户,会有一个比较明确的说明,用户会清楚的知道当前版本所公布的API还不稳定,有可能在正式发布的时候有所更改,0.x版本也不保证兼容性。(译注:以Visual Studio2000 beta2为例,与正式版的差别就非常大,所以0.x版本通常只是用来学习,或者进行技术预言,而不能在产品中使用)。但是一旦1.0版本正式发布,请记住,就是对API的兼容性就做出一个正式的承诺。象JCP组织在对某一个规范推出正式版本以前,通常都会发布若干个草稿版本(如意向草稿,公共预览草稿,最终建议版本等)。如果方便的话,对于规范性的内容,在发布API时,提供一个API的实现可能会更有效的推行规范(译注:因为规范性的内容更多的是以Interface的方式来发布API,大家可以参考一下Interface和Abstract Class,所以提供一个实现往往更好,象sun发布J2EE规范时,就提供了一个默认的实现。)。

  当API的设计和开发到了一定阶段以后,可能会发现以前的版本已经出现了一些问题,又或者需要添加新的功能,此时设计人员完全可以重新创建新的API,并放到新的包中,这样就可以保证那些使用老版本的用户可以很轻松的移植到新版本上,而不会产生问题。请牢记一点:添加新的功能,请不要修改原有的内容。

  API的设计目标

  设计一个API要达到哪位目标呢?除了兼容性以外,也从Elliotte的讨论中提出一些目标。

  API的正确性必须保证:

  以XOM为例,无论用户如何调用API,都不应该产生错误的XML文档。再如JMX,不管是注册一个错误的MBean还是并发执行一些操作,又或者MBeans使用了一些特殊的名称,MBean Server都必须保持状态的一致性,不能在某个错误的MBeans进行了操作以后,整个系统就无法提供服务。

  API的易用性:

  API必须易于使用。通常易用性一向难以评价。但是有一个办法可以有效的提高易用性,就是编写大量范例代码,并将其很好的组织在一起,从而为用户提供API参考。(译注:个人认为一个好的FAQ可以提供各种API使用的范例。)

  另外下列原则也可以用来判断API的易用性:

  是不是总是经常出现一组操作代码?(译注:这里是指如果有多行代码重复被调用,说明它们应该被放到一个方法中,避免用户重复编写一组代码。)

  在使用API时,是否需要经常参考JavaDoc或者是源代码,才能知道应该调用哪个方法呢?(译注:比较理想的情况就是,大部分操作只需要通过类名和方法的名称就可以明白)。

  根据名称调用一个方法,但是该方法所做的事并不是用户所想要的。(译注:例如调用一个command方法,以为是执行一个操作,但是结果这个方法是做备份用。)

  API必须易学:

  很大程度上,API的易学和易用性是相似的,一般来说,易用也就易学。如果要使API易学,下列基本原则要遵循的:

  •   API越小就容易学习;
  •   文档应该有范例;
  •   如果方便的话,尽可能将API与一些常用的API保持一致。例如如果要做一个资源访问的API,尽可能与J2SE中的IO使用一致,自然很容易学习。

  (译注:如果你要关闭一个资源,就象Java的File,Connection一样,使用close,而不是destroy。)

API的运行速度必须够快:

  Elliotte也是考虑了很久,才给出这一条。但是要在保证API简单而且正确的前提下,再来考虑API的性能问题。在设计API时,你可能会先使用一种能够快速实现但是性能不好的方式来实现API,然后再根据实际情况再修改API的实现,以调整性能。至于如何调整性能,绝对不要通过直觉来判断何种方式能获得高性能。只能通过正确,严格的测试以后,再对性能瓶颈进行优化从而提高性能。(译注:过早的优化是所有的错误根源,这已经是一个普遍认同的观点,特别是对于Java程序,因为它的JVM越来越快,越来越聪明。)

  API必须足够的小:

  这里所说的小不仅是指编译后代码的文件比较小,而且更重要的是运行时占用的内存要小。之所以提出最小化的概念,还有一个原因:就是因为很容易为API添加新的内容,但是要将一个内容从API中移出就很困难,所以不要随便向API中添加内容,如果不确定一项内容,就不要将它加入到API中。通过这样一个建议或者说是限制,可以提醒一个API设计人员更加关注API中最重要的功能,而非一些枝节的问题。

  (译注:许多时候这个最小化原则是很难遵守的,如不变类通常比可变类更好一些,但是它会占用更多的内存,而可变类占用的内存会少些,但要处理线程,并发等问题,所以更多时候是一个权衡,大固然不好,小也必就好)。

  有一种设计API的方法很常见,但是结果却令人头痛,这种方法就是在设计API前,会详细的考虑每一个用户的需求,并设计出相应的方法,可能在实现中还要设计一堆的Protected方法,这样使得用户可以通过继承来调整默认实现。为什么这种方法不好呢?

  因为考虑的过于详细,功能边界也就越大,所面对的需求也就越多,因此要提供的功能和可供用户调整的功能也就更加庞大,也就是说这种方法会使得API包含很多的功能,最终就是API膨胀性的增长。

  事实上API中包含的功能越多,也就更加难以学习和使用,而且其学习难度往往是以几何级数进行增长,而不是线性增长。想像一下,理解并学习使用10个类,100个方法的API对于一个程序员并不困难,大概一天就可以完成,但是对于一个100个类,1000个方法的API,即使对于一个非常优秀的程序员,估计10天的时间是不足以完全理解。

  另外在一个庞大的API中,如何才能尽快的找到最重要的内容,如何找到完成所需功能的方案,一直都是API中设计中的一个难题。

  JavaDoc工具给用户带来了许多的方便,但一直以来它都没有解决如何学习和使用一个庞大API库的方法。JavaDoc将指定包中的所有类都放置在一起,并且将一个类中的所有方法放置在一起(译注:这里指的是allclasses-frame.html,index-all.html),纵然是天才,看到成千上万的方法和类也只能抱头而泣了。现在看来,只能寄希望于JSR260标准,希望它能够有效地增强JavaDoc工具,从而可以获得API的完整视图,能够更加宏观地表示API,如果这样,即使是很庞大的API包,也不会显得拥挤,从而也就更加容易理解和使用。

  另外API越大,出现的错误可能性也就越多,与前面使用的难度一样,错误的数量也是呈几何级数增长而不是线性增长。对于小的API,投入相同的人力进行编码和测试时,可以获得更好的产出。

  如果设计的API过于庞大,必然会包含了许多不必要的方法,至少有许多public的类和方法,对于大部分用户是用不到,也会占用更多的内存,并降低运行效率。这违反了通常的一个设计原则:“不要让用户为他使用不到的功能付出代价”。

  正确的解决方案是在现在的例子上来设计API(译注:更象原型演化的方式)。先来想像一下:一个用户要使用API来解决何种问题呢,并为解决这些问题添加足够的类和方法。然后将与之无关的内容全部移除,这样可以自己来检查这些API的有用性,这种方法还会带来一个有用的附加功能,它可以更加有效测试代码。同时也可以将这些例子与同伴分享。(译注,这个概念与测试先行是非常相似的)。

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

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

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