【问题标题】:Java design patterns: Pipeline and immutability [closed]Java 设计模式:管道和不变性 [关闭]
【发布时间】:2020-08-01 13:17:19
【问题描述】:

我正在为我的后端服务开发一个轻量级框架,以支持类似管道的处理。

  • 在管道中,每个阶段本质上是一个Function<IN, OUT>,其中IN 是前一个阶段的OUT
  • 每个阶段都可以将其结果设置为数据模型(我们称之为Record
  • 虽然输入是IN(前一阶段的输出),但每个阶段都可以查看到目前所有的结果。

我的问题:

因此,从本质上讲,每个阶段都可以将其结果设置为数据模型,并且可以获得迄今为止的所有其他结果。这使得模型在管道中的所有组件之间共享和可变。

它会被视为反模式吗?如果是这样,您将对我的架构做出哪些改变?

谢谢

【问题讨论】:

  • 每个阶段仍然可以创建一个新的Record对象
  • 有点像List 实现
  • @emotionlessbananas,你能详细说明一下吗?

标签: java design-patterns etl backend stream-processing


【解决方案1】:

当线路中的组件相互独立并保持相互独立时,管道设计是好的。例如,您会看到它在 Web 服务器过滤器链(如 Apache httpd 过滤器或 Java servlet 过滤器)中使用:链中的每个“链接”都可以检查请求和响应并可能进行修改。

当组件之间产生隐藏的依赖关系时,管道设计很快就会变坏。隐藏的依赖是当链中的一个链接使用在上游链接中完成的计算结果时。这种依赖没有被类型系统捕获,也没有被测试覆盖,而且通常甚至没有记录在案。如果程序员现在修改或重构上游链接的代码,下游代码很可能会中断。在一个由多个开发人员共同开发的大型系统中,隐藏的依赖关系会很快发生,并导致代码脆弱且难以理解。

如果您看到隐藏的依赖关系形式,最好将管道设计替换为使依赖关系图显式的设计。

【讨论】:

  • 所以基本上它是 3 步管道。 A->B->C。我感到困惑的是:一方面B 需要A 的结果。另一方面,我不希望B 转换A 的结果。一种选择可能是 clone() 对象或对其进行序列化,但这对我来说似乎是一种开销。另一个非常相似的想法是只使用B 的相关数据创建一个“瘦”对象(有点像 DTO)。这是一个合理的方法吗?
  • 如果你不想让 B 修改 A 的结果,它可以直接传递而不修改。
  • 是的,我的问题是这是否是一种反模式。也就是说,B 可能会改变 A 的结果,因为它是可变的(可能)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-27
  • 2010-10-11
  • 1970-01-01
  • 2011-01-20
  • 1970-01-01
  • 2011-08-02
相关资源
最近更新 更多