- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在编写与第 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/
为什么禁用类型像 type t = A of int | B of string * mutable int 虽然允许此类类型: type t = A of int | B of string * i
我正在寻找一种类似结构的数据结构,我可以从中创建多个实例并具有某种类型提示而不是不可变的。 所以我有这样的东西: class ConnectionConfig(NamedTuple): nam
我需要转到引用的结构: class SearchKnot { var isWord : Bool = false var text : String = "" var to
如sec 10.4.3中所述 当控制进入执行时,执行以下步骤 功能对象F(调用者)中包含的功能代码的上下文 提供thisArg,而调用方提供argumentsList: 如
i make a game that start display Activity indicator And activity indicator bottom display UiLable wi
编辑:我在这里不断获得支持。只是为了记录,我认为这不再重要。自从我发布它以来我就不再需要它了。 我想在 Scala 中执行以下操作... def save(srcPath: String, destP
使用可变对象作为 Hashmap 键是一种不好的做法吗?当您尝试使用已修改足以更改其哈希码的键从 HashMap 中检索值时,会发生什么? 例如,给定 class Key { int a; /
如果您在Kotlin中访问List类型的Java值,则将获得(Mutable)List!类型。 例如。: Java代码: public class Example { public stati
我编写了 str 类(内置)的以下扩展,以便执行以下操作:假设我有字符串 "Ciao" ,通过做"Ciao" - "a"我想要的结果是字符串 "Cio" 。这是执行此操作的代码,并且运行良好: cla
使用可变对象作为 Hashmap 键是一种不好的做法吗?当您尝试使用已修改足以更改其哈希码的键从 HashMap 中检索值时,会发生什么? 例如,给定 class Key { int a; /
我正在为我的公司设计一个数据库来管理商业贷款。每笔贷款都可以有担保人,可以是个人或公司,在借款业务失败时作为财务支持。 我有 3 个表:Loan、Person 和 Company,它们存储明显的信息。
我使用二进制序列化从 C# 类中保存 F# 记录。一切正常: F#: type GameState = { LevelStatus : LevelStatus
import javax.swing.JOptionPane; public class HW { public static void main(String[] args) { Strin
使用 flatbuffer mutable 有多少性能损失? 是否“正确”使用 FlatBuffers 来拥有一个应该可编辑的对象/结构(即游戏状态) 在我的示例中,我现在有以下类: class Ga
std::function create_function (args...) { int x = initial_value (args...); return [x] () mut
我需要在 for 循环中找到用户输入的字符。我通常会这样做 如果(句子[i] == 'e') 但是因为在这里,'e' 将是一个单字母字符变量,我不知道如何获取要比较的值。我不能只输入 if (sent
我有一个这样的算法: let seed: Foo = ... let mut stack: Vec = Vec::new(); stack.push(&seed); while let Some(ne
这个问题可能看起来非常基础,但我很难弄清楚如何做。我有一个整数,我需要使用 for 循环来循环整数次。 首先,我尝试了—— fn main() { let number = 10; // An
如果我有以下结构: struct MyStruct { tuple: (i32, i32) }; 以及以下函数: // This will not compile fn function(&mut s
我希望在每个 session 的基础上指定列的默认值。下面的脚本不起作用,但描述了我想如何使用它。我目前使用的是 MySQL 5.5.28,但如果需要可以升级。 CREATE TABLE my_tbl
我是一名优秀的程序员,十分优秀!