我正在编写与第 3 方 API 网关的集成,为了使其尽可能解耦(并能够在将来更改提供程序),我创建了 3 个接口(interface),其中包含以下方法:从网关读取、写入和删除(因为我需要使用很多方法,所以我不想将所有内容都塞进一个大接口(interface)中并违反接口(interface)隔离原则)。 API网关用于处理应用程序创建和其他CRUD操作。
而且我不确定前进的最佳方式是什么。我可以创建一个像这样的界面
interface Api_Gateway_Create {
public function create_app( string $organization, string $developer_id, string $body );
// other methods.
}
然后,在进行具体实现时,我将创建一个实现此功能的类,当我需要使用它时,我需要提供三个参数。
这似乎有点限制。如果当我更换提供商时,我不再需要 $developer_id
怎么办?我可以使用一些默认值设置所有参数
interface Api_Gateway_Create {
public function create_app( string $organization,
string $developer_id = 'some-default-value',
string $body = 'some-default-value' );
// other methods.
}
但这意味着我最终会得到我可能不需要的参数,这可能会扰乱我的实现。
我想到的最后一件事是我可以只放置一个变量,然后让实现处理参数
interface Api_Gateway_Create {
public function create_app( ...$arguments_list );
// other methods.
}
在实现中我会有
class Create_App_Implementation1 implements Api_Gateway_Create {
public function create_app( ...$arguments_list ) {
list( $organization, $developer_id, $body ) = $arguments;
// Some business logic.
}
}
或
class Create_App_Implementation2 implements Api_Gateway_Create {
public function create_app( ...$arguments_list ) {
list( $organization, $app_key, $body ) = $arguments;
// Some business logic.
}
}
这样我就不需要关心我的提供商是否提供这些参数,因为我只需实现我需要的参数。
然而,这又带来了另一个问题。在使用代码中,假设一个类将通过依赖项注入(inject)使用 create_app()
方法,我需要格外小心以确保传递正确的值。这不是面向 future 的,因为我还需要更改消费类中的代码(对我来说,这似乎与接口(interface)的相反意图)。
对于第一个,我永远不必更改使用代码,因为如果我期望相同的结果(基于相同的输入参数),我不关心我使用的提供程序。但正如我所提到的,这似乎有点限制。两个提供商可能有不同的处理方式。
有人必须面对这种事情吗?处理这种情况的行业标准是什么?
我用 PHP 编写,但我认为 Java 也适合,因为它具有面向对象的性质。
最佳答案
Did anybody have to face this kind of thing and what is the industry standard of handling this?
- 我确信他们有。
- 没有“行业标准”方法可以做到这一点。
(您应该从词汇中删除“行业标准”和“最佳实践”等短语。在我看来,它们对沟通有害。阅读 "No best practices" 并思考他在说什么。)
<小时/>我对 PHP 不太熟悉,无法说出用该语言通常会采取什么措施来解决这个问题。
<小时/>在 Java 中,有两种常见的方法:
为常见情况定义许多不同的方法(或构造函数)重载;例如
public interface CreateAppApi { public String create_app(String organization, String developerId, String body); public String create_app(String organization, String developerId); public String create_app(String developerId); }
如果参数都具有相同的类型,则此方法效果不佳:不同的重载可能无法区分。
使用流畅的构建器模式;例如定义接口(interface)如下:
public interface CreateAppRequest { public CreateAppRequest organization(String value); public CreateAppRequest developer(String developerId); public CreateAppRequest body(String body); public String send(); }
并像这样使用它:
String result = new CreateAppRequestImpl().organization(myOrg) .developer(myId).body(someBody).send();
从 API 用户的角度来看,这工作得很好,而且很容易发展。 (只需添加更多方法来向 API 提供新参数并实现它们。)缺点是有更多样板代码。
Java 支持可变参数,但它们不适合您所描述的用例。 (这适用于具有可变数量的值的情况,这些值本质上意味着相同的事情;例如,表示我们假设的“应用程序”的方法的字符串内联列表。)
<小时/>在Python中,没有方法重载...因为不需要它。反而:
- 您可以使用位置参数或关键字参数,或它们的组合。
- 您还可以使用 *args
和 **kwargs
等结构来传递任意参数,而无需显式声明它们。
一般来说,关键字参数更适合需要具有不同含义和(可能)类型的各种参数的 API。
因此,在这个示例中,您可以编写如下内容:
class CreateAppRequest(SomeBaseClass):
def __init__(self, organization='defaultOrg', developer=None, body='',
**kwargs):
super(self, CreateAppRequest).__init__(**kwargs)
if developer is None:
raise Exception('developer is mandatory')
self.developer = developer
self.organization = organization
self.body = body
def send(self):
...
构建器/流畅方法也可以在 Python 中使用。
关于java - 在带有特定或可变参数的接口(interface)中编写方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57326576/