api 文档和“价值限制”:它们匹配吗?
Posted
技术标签:
【中文标题】api 文档和“价值限制”:它们匹配吗?【英文标题】:api documentation and "value limits": do they match? 【发布时间】:2010-09-08 20:43:08 【问题描述】:您是否经常在 API 文档(例如“公共函数的 javadoc”)中看到“值限制”的描述以及经典文档?
注意:我不是在说comments within the code
“价值限制”是指:
参数是否可以支持空值(或空字符串,或...)? “返回值”是否可以为 null 或保证永远不会为 null(或可以为“空”,或者...)?示例:
我经常看到的(无法访问源代码)是:
/**
* Get all readers name for this current Report. <br />
* <b>Warning</b>The Report must have been published first.
* @param aReaderNameRegexp filter in order to return only reader matching the regexp
* @return array of reader names
*/
String[] getReaderNames(final String aReaderNameRegexp);
我希望看到的会是:
/**
* Get all readers name for this current Report. <br />
* <b>Warning</b>The Report must have been published first.
* @param aReaderNameRegexp filter in order to return only reader matching the regexp
* (can be null or empty)
* @return array of reader names
* (null if Report has not yet been published,
* empty array if no reader match criteria,
* reader names array matching regexp, or all readers if regexp is null or empty)
*/
String[] getReaderNames(final String aReaderNameRegexp);
我的意思是:
当我使用一个包含 getReaderNames() 函数的库时,我通常甚至不需要阅读 API 文档来猜测它的作用。但我需要确定如何使用它。
当我想使用这个函数时,我唯一关心的是:在参数和返回值方面我应该期待什么?这就是我安全设置参数和安全测试返回值所需要知道的全部内容,但我几乎从未在 API 文档中看到此类信息...
编辑:
这会影响 checked or unchecked exceptions 的使用与否。
你怎么看?值限制和API,它们是否属于一起?
【问题讨论】:
【参考方案1】:我认为他们可以属于一起,但不一定必须属于一起。在您的场景中,似乎有必要将限制记录在生成的 API 文档和智能感知中(如果语言/IDE 支持的话)。
我认为这也取决于语言。例如,Ada 有一个本地数据类型,它是一个“受限整数”,您可以在其中定义一个整数变量并明确指出它只会(并且总是)在某个数字范围内。在这种情况下,数据类型本身表示限制。它仍然应该通过 API 文档和智能感知可见和可发现,但开发人员不必在 cmets 中指定。
但是,Java 和 C# 等语言没有这种类型的受限整数,因此如果它是应该成为公共文档一部分的信息,开发人员必须在 cmets 中指定它。
【讨论】:
【参考方案2】:我认为这些边界条件绝对属于 API。但是,我会(并且经常这样做)更进一步,并指出这些空值的含义。要么我表明它会抛出异常,要么我解释传入边界值时的预期结果。
很难记住总是这样做,但这对您班级的用户来说是件好事。如果方法提供的合同发生更改(例如将空值更改为不允许),也很难维护它......当您更改方法的语义时,您还必须勤奋更新文档。
【讨论】:
【参考方案3】:问题 1
您是否经常在 API 文档(例如“公共函数的 javadoc”)中看到“值限制”的描述以及经典文档?
几乎没有。
问题 2
当我想使用这个函数时,我唯一关心的是:在参数和返回值方面我应该期待什么?这就是我安全设置参数和安全测试返回值所需要知道的全部内容,但我几乎从未在 API 文档中看到此类信息...
如果我不正确地使用了一个函数,我会期望该方法抛出一个RuntimeException
,或者在程序的另一个(有时很远)部分出现RuntimeException
。
@param aReaderNameRegexp filter in order to ... (can be null or empty)
之类的评论在我看来是一种在 Javadoc 中以人类语言实现 Design by Contract 的方法。
iContract
使用 Javadoc 来强制按合同设计,现在又被重新命名为 JcontractS
,它允许您指定不变量、前置条件、后置条件,与人类相比,它以更正式的方式 -是语言。
问题 3
这会影响检查或未检查异常的使用与否。 你怎么看 ?值限制和API,它们是否属于一起?
Java 语言没有按合同设计的功能,因此您可能会想使用Execption
,但我同意您的观点,即您必须了解When to choose checked and unchecked exceptions。可能您可能会使用未经检查的IllegalArgumentException
、IllegalStateException
,或者您可能会使用单元测试,但主要问题是如何与其他程序员沟通此类代码是关于按合同设计的,并且在更改之前也应将其视为合同轻轻的。
【讨论】:
这个问题很有趣(5 年后)。 +1。我同意“按合同设计”方面。【参考方案4】:我认为他们会这样做,并且总是将 cmets 放在头文件 (c++) 中。
除了有效的输入/输出/返回 cmets,我还注意到函数可能会抛出哪些异常(因为我经常想将返回值用于......以及返回一个值,我更喜欢异常而不是错误代码)
//File:
// Should be a path to the teexture file to load, if it is not a full path (eg "c:\example.png") it will attempt to find the file usign the paths provided by the DataSearchPath list
//Return: The pointer to a Texture instance is returned, in the event of an error, an exception is thrown. When you are finished with the texture you chould call the Free() method.
//Exceptions:
//except::FileNotFound
//except::InvalidFile
//except::InvalidParams
//except::CreationFailed
Texture *GetTexture(const std::string &File);
【讨论】:
【参考方案5】:@Fire Lancer:没错!我忘记了异常,但我希望看到它们被提及,尤其是这个公共方法可能抛出的未经检查的“运行时”异常
@迈克·斯通:
当您更改方法的语义时,您还必须努力更新文档。
嗯,我当然希望 公共 API 文档 至少在发生更改(影响函数契约)时进行更新。如果没有,这些 API 文档可能会被完全删除。
为了增加你的想法(和@Scott Dorman 一起去),我偶然发现了the future of java7 annotations
这是什么意思?某些“边界条件”,而不是在文档中,应该在 API 本身中更好,并在编译时自动使用适当的“断言”生成代码。
这样,如果 API 中有一个“@CheckForNull”,那么函数的编写者可能会侥幸逃脱,甚至不记录它!如果语义发生变化,其 API 将反映该变化(例如“不再有 @CheckForNull”)
这种方法表明,对于“边界条件”,记录是一种额外的好处,而不是强制性的做法。
但是,这不包括函数返回对象的特殊值。为此,仍然需要完整文档。
【讨论】:
您会惊讶于开发人员在更改方法的语义时经常不更新他们的 javadoc... 我见过很多。也就是说,框架和语言本身通常都很好。 新的注解:如果它们出现真是太棒了,但你仍然需要用@Nullable 来记录空值的语义。我发现最好非常明确地传递 null 实际会做什么,@Nullable 仅表明它是允许的,而不是它的作用。 @Mike Stone 同意,看来文档毕竟是强制性的... 至于 javadoc,我同意:事实上,在我的 200 个开发人员项目中,很少记录公共 api 的 javadoc! (叹气!)以上是关于api 文档和“价值限制”:它们匹配吗?的主要内容,如果未能解决你的问题,请参考以下文章
Python Google Map API提供的OSM_type与文档不匹配
这是文档中的错误吗? -existingObjectWithID:error: 或 -objectWithID: 似乎声称不同的东西不匹配