3

在定义客户可访问的 API 时,以下之间的首选行业实践是什么:

a)定义一组显式API 方法,每个方法都有一个非常狭窄和特定的目的,例如:

SetUserName    <name>
SetUserAge     <age>
SetUserAddress <address>

b)定义一组更通用的基于参数的 API 方法,例如:

SetUserAttribute <attribute>

enum attribute {
    name,
    age,
    address
}

我的意见:

赞成(一)

对于基于布尔值的方法(例如 EnableFoo),我肯定会支持选项 (a),因为其意图更加清晰,将来需要扩展的可能性较小,并且它使代码更具可读性。

例如,一个名为 EnableDisableFoo 的方法接受一个布尔参数来指示是启用还是禁用,这将不是很清楚,也没有凝聚力的目的。

这是有多种选择的地方,问题变得更加复杂。

赞成(b)

选项 (b) 是在 API 中提供可扩展性的好方法,但会牺牲可用性。使用选项 (a),API 方法名称本身提供了足够的信息来指示它正在做什么。使用选项 (b),用户必须查找方法名称和要使用的适当枚举/参数。理论上,从可用性的角度来看,这会使选项 (b) 变得更糟——但也许使用较少的方法是一件好事,所以即使这也不完全正确。

其他想法

有必要在可用性和可扩展性之间取得良好的平衡,而且它们之间经常存在矛盾。但我想有一种更客观的方法来分析这一点,而不是依赖 API 设计者的意见。

有人对此有任何想法吗?

4

3 回答 3

2

我个人赞成(a),因为我们的目标是使“静态”代码尽可能准确和可靠。

通过使用广义形式,我们引入了运行时错误的风险。例如,我可以设置一个年龄类型的属性,其值实际上是一个字符串,等等。

这与定义和使用枚举或显式类型而不是在旧 C 风格中使用和返回 int 的论点非常相似,因为您可以获得更高级别的保证。

虽然我同意 (b) 允许可扩展性,但我还没有看到太多 API 需要对完全不同类型的属性进行这种可扩展性。(b) 的唯一常见用途是在多态代码中,该函数在技术上可以接受任何东西,包括扩展。

于 2009-01-28T05:42:15.530 回答
1

另一个考虑因素是您是否要设置所有属性并同时设置它们。例如,当您想向打印机发送内容时,可能需要设置几十个参数(横向或纵向;份数;页面大小;分辨率等)。你可以定义一个函数,而不是定义一个需要调用几十次的API,它以astruct为参数,其中struct包含几十个字段,调用者struct在空闲时初始化,然后传递struct在单个函数调用中进入 API。

于 2009-01-28T05:47:07.830 回答
0

我认为这取决于您正在编写的代码。如果你写的东西总是在一起的(即,如果你要使用/更改年龄总是与名字一起),那么选择 b,否则 a 很好。

但是不要试图过度做(a),因为那样你只会写更多的行并且完成的工作会少很多。好主意,如果你为你写的代码量付费:)

于 2009-01-28T06:45:32.377 回答