|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
在1995年5月23日以“Java”的名称正式发布了。Java言语依照Javadoc正文商定接纳了一种集成的办法来举行API文档体例。Javadoc工具能够匡助天生好的API文档,但是年夜多半JavaAPI文档却很糟。由于它是源代码的一部分,以是API的文档体例职责终极仍是落到了工程师身上。在本文中,Brian对Java文档体例理论确当前形态举行了严峻的品评,同时供应了一些关于怎样编写更有效的Javadoc的原则。
关于年夜多半Java类库来讲,Javadoc是独一的文档。并且,除贸易软件组件以外,很多Java类不会用到Javadoc。固然Javadoc作为API参考工具很杰出,但关于懂得类库是怎样构造的和应当怎样利用它来讲,它倒是一种非常低劣的办法。而且即使用了Javadoc,它一般只包括有关办法完成了甚么的最基础信息,而疏忽了诸如毛病处置、参数及前往值的感化域和局限、线程平安、锁定举动、前置前提、后置前提、稳定前提或反作用之类的主要特征。
向Javadoc进修
关于包含年夜多半开放源码包和年夜多半外部开辟的组件在内的很多Java工具而言,实践情形是:包含Javadoc在内,几近一切类库或组件都不具有无效的文档。这就意味着开辟职员要从Javadoc进修利用工具,并且我们应当思索依据这一实际构造我们的Javadoc。我常常开顽笑说:如今,Java程序员必要具有的最主要的妙技之一是纯熟地利用Google和Javadoc来对那些文档体例得非常糟的API举行“逆向工程”。这多是真的,但却其实不非常可笑。
年夜多半Java包都有某种“根”对象,它是在失掉该工具内的任何别的对象之前,必需创立的第一个对象。在JNDI中,该根对象是Context,而在JMS和JDBC中,它是Connection。假如有人告知您JDBC中的基本对象是Connection,和怎样取得这一对象,那末接着您极可能会从Javadoc中经由过程细心观察Javadoc中可用的办法列表找到怎样创立并实行Statement,和怎样迭代天生的ResultSet。但您怎样晓得取得Connection是您的第一步呢?Javadoc在包内依照字母按次构造类,在类中依照字母按次构造办法。遗憾的是,Javadoc中没有奇妙的“从这里入手下手(StartHere)”暗号把读者带到扫瞄API的逻辑入手下手地位。
包形貌
最靠近“从这里入手下手”暗号的是包形貌,但它却很少失掉无效的利用。假如将文件package.html与源代码一同放在一个包中,那末尺度的doclet会将已天生的package-summary.html文件中的内容连同类列表一同放在该包内。遗憾的是,天生我们都很熟习的HTML文档的尺度doclet却没法使包形貌易于找到。假如您单击左上窗格中的某个包,那末这会在左下窗格中发生办法列表,但其实不会在主窗格中发生包的择要―必需单击左下窗格中的包称号来检察择要。但没关系,究竟年夜多半包并没有包形貌。
包文档是一个安排“从这里入手下手”文档的极好的中央,这一文档用来概述包做甚么、次要择要是甚么和从那边入手下手扫瞄包的Javadoc。
类文档
除包文档以外,特定于类的文档关于匡助用户完全懂得新工具也能起到主要的感化。类文档固然应当包含此特定类做甚么的形貌,但还应当形貌该类与包中的别的类怎样联系关系,出格是要标识任何与该类相干的工场类。比方,JDBC中的Statement类文档应当申明:Statement是经由过程Connection类的createStatement()办法取得的。如许,假如一个新用户偶尔进进Statement页面,那末他会发明起首他必要取得Connection。对每一个类都使用这一商定的包会敏捷为用户指出根对象,用户因此可以轻车熟路。
由于Javadoc是环绕对特定类举行文档体例而计划的,因而在Javadoc中一般没有分明的地位来安排演示几个相干类一同利用的示例代码。但因为一味地偏重于特定类或办法的文档体例,我们得到了会商怎样组合包中内容的时机。假如关于根对象,在包文档或类文档中有一个演示一些基础用法的复杂代码示例,则关于很多用户来讲,将长短常有效的。比方,Connection类文档能够有一个复杂示例,该示例猎取毗连、创立预编译语句、实行该语句并迭代了局集。从手艺上说,这大概不属于Connection页面,由于它还形貌了包中的别的类。但是,特别是当分离了下面那种援用以后类所依附的类的手艺时,用户才干十分敏捷地找到猎取复杂的有用示例的路子,不论类的构造体例怎样。
糟的文档==糟的代码
关于年夜多半Java类库来讲,除那些作为打包组件出卖的贸易产物以外,要末没有Javadoc,要末十分糟。因为存在的现实是关于年夜多半包来讲,Javadoc是我们具有的独一文档,这基础上意味着使我们本人堕入了如许的窘境:除作者以外,其别人没法利用我们的年夜部分代码―假如不支付严重的“考古”一样的勉力,最少会如许。
因为文档如今是代码的一部分,因而我以为是软件工程社区构成一个共鸣的时分了,这就是,即便代码很杰出,假如文档很糟,也应当被以为是低劣的代码,由于不克不及无效地重用。单位测试不久前还名誉欠安,只是到了比来它才遭到了很多工程师的喜爱,就和它一样,为了改良我们临盆的软件的牢靠性和可重用性,API文档也必需成为开辟历程的一个集成部分。
编写Javadoc就是某种情势的代码反省
编写公道的Javadoc也会发生反作用,它迫使我们举行某种情势的代码反省,来研讨类的系统布局和它们之间的干系。假如单个包、类或办法很难体例文档,那末也许能够实验同时对多个包、类或办法举行文档体例,这应当是个提醒,便可能它必要从头计划。
文档的自我反省方面使得某些方面加倍主要,即在开辟过程当中尽早编写Javadoc,然后跟着代码的不休开辟,按期对其举行反省,而不是仅仅守候代码完成再编写文档(假如有残剩工夫的话)。后一种战略非常罕见,它将编写文档拖到项目最初,而当时工夫布置非常严重,开辟职员的压力也很年夜。了局再罕见不外了,就是所示的那种一文不值的文档,它只供应了“文档假象”。用户真正必要的是懂得该类的事情道理,而该文档却没有供应任何如许的信息。
清单1.典范的一文不值的Javadoc
/**
*Representsacommandhistory
*/
publicclassCommandHistory{
/**
*Getthecommandhistoryforagivenuser
*/
publicstaticCommandHistorygetCommandHistory(Stringuser){
...
}
}
那末好的文档包含哪些内容呢?
下面形貌的构造手艺(在类形貌中援用相干类或工场类,也包含了包概述和代码样本)是构成优异文档的好初步。它有助于新用户利用Javadoc懂得新工具。
但系统布局的概述只完成了义务的一半。另外一半则是具体地注释办法做甚么和不做甚么、在甚么前提下运转和它们怎样处置毛病前提。年夜多半Javadoc都没有完整供应所需的信息,即使是那些充实形貌了办法在希冀情形下的举动的Javadoc也是云云,这些短少的信息包含:
办法怎样处置毛病前提或分歧请求的输出
怎样将毛病前提传回给挪用者
大概会抛出哪一个特定非常的子类
哪些值关于输出是无效的
类稳定前提、办法前置前提或办法后置前提
反作用
在办法之间是不是有主要连接
类怎样处置多个线程同时会见一个实例的情形。
Javadoc商定供应了@param标志,它让我们除可以对参数的称号和范例体例文档以外,还能够对其意义体例文档。但是,并非一切的办法都能很好地承受参数的任何值。比方,固然能够正当地向任何猎取对象参数的办法传送空值(null)而不违背范例反省划定规矩,但并非一切的办法都能在传进空值时一般事情。Javadoc应当显式地形貌无效的参数局限,假如它但愿某个参数非null,那末它应当如许形貌,而假如它希冀参数值在某个局限内,比方某种长度的字符串或年夜于0的整数,那末它也应当那样形貌。并不是一切办法都细心反省其参数的无效性;不举行无效性反省也没有体例关于可承受的输出局限的文档,这两者的分离为劫难埋下了隐患。
前往代码
Javadoc使得形貌前往值的意义变得很简单,但正如办法参数一样,@return标志应当包含对大概前往的值局限的具体形貌。关于对象取值的前往范例而言,它会前往空值吗?关于整数取值的前往范例而言,了局会限定在一个已知值或非负值的汇合上吗?任何前往代码都有特别意义吗,比方从java.io.InputStream.read()前往-1暗示文件停止符?前往代码会被用来暗示比方假如没法找到表项则前往空值那样的毛病前提吗?
非常
尺度doclet复制办法的throws子句,但Javadoc@throws标志应当更加详细。比方,NoSuchFileException是IOException的子类,但java.io中的年夜多半办法却只被声明为抛出IOException。但是,办法大概自力于别的IOException而抛出NoSuchFileException,这是挪用者要懂得的很有效的现实―它应当被包含在Javadoc中。还应当指出抛出各类非常类的实践毛病前提,以便挪用者晓得在给定非常被抛出时该接纳甚么改正措施。应当用@throws标志对办法大概抛出的每一个经反省的或未经反省的非常体例文档,并对激发抛出非常的前提体例文档。
前置前提、后置前提和稳定前提
固然,您应当对办法对对象形态的影响体例文档。但您大概必要体例得更具体一些,形貌办法的前置前提、后置前提和类稳定前提。前置前提是在挪用办法前对对象形态的束缚;比方,挪用Iterator.next()的前置前提是hasMore()为真。后置前提是办法挪用完成后对对象形态的束缚,比方在挪用add()以后List不克不及为空。稳定前提是对对象形态的一种束缚,它包管该形态一直为真,比方Collection.size()==Collection.toArray().length()。
诸如jContract之类的按左券计划(Design-by-contract)工具同意您利用特别正文指定前置前提、后置前提和类稳定前提,这类工具然后天生分外代码来强迫这些束缚。不管您是不是利用工具来强迫这些希冀前提,对这些束缚体例文档可让用户晓得要平安地利用类,他们能够做些甚么。
反作用
偶然候,办法除改动对象形态以外还会有别的反作用,比方改动相干对象、JVM或底层盘算平台的形态。比方,一切实行I/O的办法都有反作用。有些反作用是有害的,比方保存类处置的哀求的记数。别的一些反作用则会对程序功能和准确性发生严重影响,比方修正传送给办法的对象的形态,或存储对该对象的援用的正本。诸如修正相干对象的形态或存储对作为办法参数传送的对象的援用之类的反作用应当体例文档。
办法连接
办法连接意味着类中的两个办法互相依附,而且都对对方的举动做了假定。产生办法连接的一种罕见情况是:办法在外部利用统一个类的toString办法,并假定toString将以出格的办法格局化对象形态。假如该类已子类化而且toString办法被重写了,那末这类情况大概引发成绩;另外一个办法会俄然不克不及一般事情,除非它也被重写。假如您的办法依附于别的办法的完成举动,那末必要对那些依附性体例文档。并且,假如类已子类化,那末能够以分歧的体例重写两种办法以便使子类仍能一般事情。
线程平安
应当体例文档的最主要的举动之一是线程平安,而对它几近从未体例文档。这个类是线程平安的吗?假如不是,那末是不是能够经由过程用同步封装挪用来使其线程平安吗?这些同步必需同特定管程相干联,仍是任何一向利用的管程都可使用呢?办法取得了关于类内部是可见的对象的锁吗?
线程平安实践上不是二进制属性;线程平安有几种可标识的品级。对线程平安体例文档,大概乃至断定线程平安的品级并不是老是很简单。但未能举行这一事情将招致严峻的成绩;在并发使用程序中利用非线程平安类大概引发零散的妨碍,这些妨碍经常直到部署时才呈现(当时表露使用程序以便装进)。并且将分外锁定封装在已是线程平安的类四周会影响功能,乃至引发逝世锁。
JoshBloch在他的EffectiveJavaProgrammingLanguageGuide(参阅参考材料)一书中对类的线程平安品级体例文档供应了有效的分类法。能够依照线程平安递加按次将类回到以下某一组:不成变、线程平安、有前提的线程平安、线程兼容和线程对峙。
这类分类是一个极佳的框架,用于在并发会见情形下传送关于类举动的主要信息。不论您是不是利用这一分类法都不妨,但您应当标识您的类企图显现的线程平安品级。我还倡议:假如办法取得对一个对象的锁定,而该对象关于类本身的代码内部是可见的,那末您也应当就此体例文档,即便这只是一个“完成细节”,以便帮忙做出全局锁定按次(global-lock-order)决议并避免逝世锁。
停止语
对类的举动体例文档远远不但是对每一个办法做甚么给出一行形貌。无效的Javadoc应当包含对以下内容的形貌:
类怎样互相联系关系
办法怎样影响对象的形态
办法怎样将堕落前提关照它们的挪用者和它们大概关照甚么毛病
类怎样处置多线程使用程序中的利用
办法的参数感化域及其前往值的局限
别的,糟的文档(或乃至更糟,没有文档)会招致优异的代码不成用或不成重用。经由过程在文档上花一些分外工夫,您将为您的用户(多是您本人)制止有数的波折。
Java到底会发战成什么样,让我们拭目以待吧,我始终坚信着java会更好。以上都是俺个人看法,欢迎大家一起交流. |
|