将 ETag 传递到输入端口哪种方法更好:作为域对象还是作为字符串?

问题描述 投票:0回答:1

我正在开发一个项目,需要将 ETag 作为参数传递到输入端口,特别是像 getDocument(ETag eTag) 这样的方法。但是,我不确定在设计和最佳实践方面将 ETag 传递到输入端口的最佳方法。

我应该将 ETag 作为域对象 (ETag) 还是作为字符串传递?以下是一些注意事项:

  • 语义:将 ETag 作为域对象传递可以在我的代码库中提供更丰富、更语义有意义的 ETag 表示。然而,在某些情况下,将其作为字符串传递可能更简单、更直接。

  • 强类型和安全性:将 ETag 作为域对象传递可以利用强类型,这可以通过确保仅将有效的 ETag 传递给方法来帮助防止错误并提高安全性。另一方面,将其作为字符串传递可能不太容易出错,但缺乏域对象提供的类型安全性。

  • 清晰度和表现力:将 ETag 作为字符串传递可能会更清晰、更具表现力,特别是在使用域对象增加不必要的复杂性或混乱的情况下。

  • 可用性和简单性:为了简单性和易用性,将 ETag 作为字符串传递可能更可取,特别是在处理域对象会增加不必要的开销或者 ETag 验证在该上下文中并不重要的情况下。

考虑到这些因素,我有兴趣听取社区的意见:您建议采用什么方法将 ETag 传递到输入端口,以及在做出此决定时我应该考虑哪些因素?我应该遵循哪些最佳实践或设计原则?

ETag 是一个值对象。实体或聚合怎么样?它们应该存在于应用程序层和域层中吗?

预先感谢您的见解!

domain-driven-design clean-architecture
1个回答
0
投票

您所描述的问题的通用版本(无论是使用通用数据结构还是专用“对象”传递数据)的标签是原始痴迷(来自 Kent Beck 和 Martin Fowler 的《代码中的坏味道》,1999 年)。

每个人都同意,当收益大于成本时,您应该使用“值对象”而不是通用数据结构。同样,每个人都同意,当使用“值对象”的成本超过收益时,您应该使用通用数据结构。

然而,在评估成本和收益时会出现分歧,而且我们没有一个权威机构可以给我们一个正确的答案[tm]。那么:“这取决于”?


IANA HTTP 字段注册表告诉我们,ETag 字段的参考当前是 RFC 9110。该规范告诉我们一些有趣的事情:

  • 并非任何字符串都可以用作 ETag;有一个产生式规则限制了我们需要考虑的字符串域
  • 使用的拼写区分
  • 强验证器和弱验证器
这里的要点是,我们可能想要隐藏 ETag 的一些细节(在

Parnas 1971 意义上);并不是因为细节可能会发生变化(http-wg 在保持标准中的向后兼容性方面非常出色,但 ETag 定义确实相对于 RFC 2616 发生了足够大的变化,足以证明当前标准中的注释是合理的),而是因为这些细节不相关。

因此,我们可能更愿意将其移动到一个单独的库中,而不是将一堆解析/分支标签混合到我们的逻辑中。

verb(opaqueString: String) { if (ETagLibrary::isWeakValidator(opaqueString)) ... }
现在与更抽象数据类型的方法进行比较

verb(opaqueHandle: ETagLibrary::Handle) { if (ETagLibrary::isWeakValidator(opaqueHandle)) ... }
这里显然有一个缺点,因为你必须在某个地方举行一些仪式才能获得

ETagLibrary::Handle

;但作为补偿,您可以修改数据结构,特别是您可以在该数据结构中保存缓存的答案(相比之下,通用
String
不提供任何方便的位置来缓存“isWeakValidator”答案,或我们可以在解析阶段预先计算的其他值)。

您可以采用相同的方法,引入 ETag 域对象作为句柄:

verb(eTag: ETag) { if (ETagLibrary::isWeakValidator(eTag)) ... }
但是使用域对象方法支持引入

seam,它允许您从依赖于答案的代码中隐藏 ETagLibrary 本身:

verb(eTag: ETag) { if (eTag.isWeakValidator()) ... }
换句话说,我们可以通过修改eTag实现的细节来改变

verb

的行为。例如,这可以让我们对 ETag 合约的许多
不同实现使用相同的动词方法。

因此,采用值对象路线可以提高内聚性(电子标签的详细信息都集中在一个地方),并且即使合约底层的实现发生变化,也可以提高客户端代码的稳定性。

这些好处可以抵消成本吗?在某些情况下?是的。在大多数情况下?或许。在所有情况下?这似乎根本不可能。

© www.soinside.com 2019 - 2024. All rights reserved.