我最近设计了一个API来包装数据存储实现,并允许其他开发人员使用此API来索引他们的数据和基于关键字查询数据。我在查询方法中使用了响应/回复模式,因为Jaroslav Tulach提到它可以避免在需要添加参数时不断更改API接口(实用API设计中的第97页)。其他开发人员认为使用方法重载是更好的方法。你能分享一下你在设计中使用两种不同方法的经验吗?下面是我和其他开发人员之间的对话。
Me:响应/回复模式看起来是一种干净的方式,因为随着API的发展,越来越多的参数可以添加到API接口中。在接口中使用多个10+重载方法只会让其他开发人员感到困惑。他们是如何决定使用哪种方法的?
其他开发人员的论点:随着API的发展,您不应该一直添加参数。如果您一直在API接口中添加参数,那么您的API设计就有问题。因此,重载方法的数量很少,所以不会给开发人员带来麻烦。此外,Java框架中经常会出现大量重载方法的实现。
Me:很容易管理对以前版本的API的向后兼容性。你不需要改变界面。更改界面会破坏其他开发人员的现有代码。
其他开发人员的论点:如果我更改实现并添加参数,其他开发人员应该基于新的API更新他们的代码。如果新参数是可选的,为什么还要麻烦地添加它。
发布于 2012-10-10 16:27:48
其他开发人员的论点:随着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);
}(接口的结构取决于实现的类型)
现在我们有了一个新的要求:所有的用户都应该包括年龄。
我们将遵循开放/关闭原则并继承reply类:
public class GetUserReply2 : GetUserReply
{
string Id;
string DisplayName;
int Age;
}所有版本1用户将反序列化版本1,而版本2用户将其反序列化为version2。
传入的参数也是如此。您可以使服务( api )类成为代理(代理模式),它仅在后台调用正确的api实现,具体取决于请求类的版本。
结论: Request/Reply给了我们更多的灵活性来对抗方法重载。
发布于 2012-10-10 16:14:50
我相信我们是在比较
invoke( int param1, string param2) { ... }
invoke ( string param3, int param4, int param5) { ... }对于所有有效的参数组合,依此类推。
使用
invoke(requestClass theRequest)它的用法如下
request.set("param1", value);
request.set("param2", value);
invoke(request);这里有几个权衡。
请求方法的一个缺点是调用者可以提供无效的参数组合,并且不会收到编译时警告-错误直到运行时才会被发现。
但不断增长的接口可能会完全失控,你可能会在所需方法的数量上出现组合爆炸。
您可以将SQL视为一个非常丰富的请求的示例--在我看来,在某些情况下,结构良好的查询语言或请求对象比一个参数一个参数的方法重载方法更可取。
我个人的经验法则是:如果你打算使用10种不同的重载方法,那么应该考虑一个请求对象。
发布于 2012-10-10 02:35:14
没有本质上的区别,也不能降低固有的复杂性。当然,我们总是可以找到支持这两种选择的用例;如果不知道你的具体问题域,其他人就不能仅仅基于一些抽象的原则来选择一个最喜欢的。
不过,我会建议您选择一种简单的解决方案。不要担心“未来的变化”
https://stackoverflow.com/questions/12805299
复制相似问题