java - 在带有特定或可变参数的接口(interface)中编写方法?

标签 java php interface implementation

我正在编写与第 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?

  1. 我确信他们有。
  2. 没有“行业标准”方法可以做到这一点。

(您应该从词汇中删除“行业标准”和“最佳实践”等短语。在我看来,它们对沟通有害。阅读 "No best practices" 并思考他在说什么。)

<小时/>

我对 PHP 不太熟悉,无法说出用该语言通常会采取什么措施来解决这个问题。

<小时/>

在 Java 中,有两种常见的方法:

  1. 为常见情况定义许多不同的方法(或构造函数)重载;例如

        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);
        }
    

    如果参数都具有相同的类型,则此方法效果不佳:不同的重载可能无法区分。

  2. 使用流畅的构建器模式;例如定义接口(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/

相关文章:

java - 使用resteasy @Path注释时出现NoClassDefFoundError

java - Univocity Parser 尝试解析文件,但出现错误

php - 将数据保存到Yii中具有两个模型的两个数据库表

php - 使用 ODBC 连接 MS Access 时如何更改连接字符集?

c# - HierarchicalDataTemplate.DataType是接口(interface),如何实现2层TreeView

java - iText 中的 PdfPageEventHelper

java - 无法使用 Maven 依赖项在 m2 存储库中下载 .jar 文件

php - Magento 支付审查/可疑欺诈工作流程

c# - 查明(上行)实例是否未实现特定接口(interface)的最佳方法

java - 在泛型类中扩展 Interface 时出现 NoSuchFieldError