3

我最近设计了一个 API 来包装数据存储实现,并允许其他开发人员使用这个 API 来索引他们的数据并根据关键字查询数据。我在查询方法中使用了响应/回复模式,因为 Jaroslav Tulach 提到它可以避免在需要添加参数时不断更改 API 接口(Practical API Design 中的第 97 页)。其他开发人员认为使用方法重载是更好的方法。你能分享你在设计中使用两种不同方法的经验吗?以下是我和其他开发人员之间的对话。

我:响应/回复模式看起来是一种简洁的方式,因为随着 API 的发展,越来越多的参数可以添加到 API 接口中。在接口中拥有超过 10 种以上的重载方法可能会让其他开发人员感到困惑。他们如何确定使用哪种方法?

其他开发者的论点:随着 API 的发展,您不应该继续添加参数。如果您在 API 接口中不断添加参数,则说明您的 API 设计存在问题。结果,重载方法的数量很少,因此不会打扰开发人员。更重要的是,Java框架中经常看到大量的重载方法实现。

我:管理以前版本的 API 的向后兼容性很容易。您不必更改界面。更改界面会破坏其他开发人员的现有代码。

其他开发人员的论点:如果我更改实现并添加参数,其他开发人员应该根据新的 API 更新他们的代码。如果新参数是可选的,为什么还要添加它。

4

3 回答 3

2

其他开发者的论点:随着 API 的发展,您不应该继续添加参数。如果您在 API 接口中不断添加参数,则说明您的 API 设计存在问题。

这是一种相当幼稚的看法。所有 API 都在发展。这不是我们想要的,但请告诉我一个客户/客户第一次就完成了规范……

请求/回复类型的参数很棒,因为它很容易获得向后可比性。一旦创建了 api 的第二个版本,我们也不必修改现有代码。

考虑一下:

public class GetUserRequest
{
    string Id;
}

public class GetUserReply
{
  string Id;
  string DisplayName;
}

以及API接口:

public class MyCoolApi
{
    GetUserReply GetUser(GetUserRequest request);
}

(API 的结构取决于实现的类型)

现在我们得到一个新要求:所有用户都应该包含年龄。

我们就按照开闭原则,继承回复类:

public class GetUserReply2 : GetUserReply
{
  string Id;
  string DisplayName;
  int Age;
}

所有版本 1 用户将反序列化版本 1,而版本 2 用户将其反序列化为版本 2。

传入参数也是如此。您可以使服务(API)类成为代理(代理模式),它只是根据请求类版本在后台调用正确的 api 实现。

结论:请求/回复为我们提供了更多的灵活性,而不是方法重载。

于 2012-10-10T08:27:47.907 回答
1

I believe we are comparing

   invoke( int param1, string param2) { ... }

   invoke ( string param3, int param4, int param5) { ... }

and so on for all valid parameter combinations

with

   invoke(requestClass theRequest)

which is used like this

   request.set("param1", value);
   request.set("param2", value);
   invoke(request);

There are several trades-off here.

A downside of the request approach is that the caller can provide an invalid combination of parameters and will receive no compile time warning - errors are not uncovered until runtime.

But the ever-growing interface may get completely out of hand, you can get a combinatorial explosion in the number of methods you need.

You can view SQL as an example of a very rich request - it seems clear to me that there are situations where a well structured query language or request object is preferable to a parameter-by-parameter method overloading approach.

My personal rule of thumb: if you're heading for 10 different overloaded methods a request object should be considered.

于 2012-10-10T08:14:49.680 回答
0

没有本质的区别,也不能降低内在的复杂性。当然,我们总能找到任何一种选择的支持用例;在不了解您的具体问题领域的情况下,其他人不能仅仅根据一些抽象原则选择一个最喜欢的。

不过,我会建议选择一个对今天来说简单的解决方案。不要担心“未来的变化”

于 2012-10-09T18:35:13.970 回答