这是数组中回退服务的设计模式
Which is the Design Pattern of Fallback services in an array
假设我已经看到 FallbackCompositeService
客户端对象使用它来获得具有回退机制的结果。
它使用 doSomething()
.
方法实现 FallbackServiceInterface
我们有一个提供服务的 DI 容器,它是用一系列具体的回退策略实例化的(这里是伪PHP示例):
new FallbackCompositeService([
new Rule1FallbackService(),
new Rule2FallbackService(),
...
])
每个回退服务也实现 FallbackServiceInterface
,因此它们也 doSomething()
。
当我们调用 $result = $fallbackCompositeService->doSomething()
时,该服务循环通过其子服务调用相同的方法,第一个非空规则响应 "wins" 并返回。
问题是:
- 此实现是复合模式的 "degenerate" 版本(因此得名)吗?
- 或者它是责任链的"degenerate"版本(其中
nextHandler()
指针被简化为通过数组的迭代)?
- 或什么 else/undefined/both/whatever...?它的潜在缺点是什么?
复合模式设想创建一个包含复合节点和叶节点的树结构——例如由表达式解析器生成的树结构。所有节点都具有相同的接口并包含它们自己的 evaluate() 实现。当在头节点上调用 evaluate() 时,所有节点都将提供最终答案的一部分(按照树遍历规定的正确顺序 - 假设解析器知道它在做什么!)。这与您的示例不同,您的示例在一个节点完成其工作时处理停止。
责任链设想了一个 linked 对象列表 - 每个对象都实现相同的接口,例如 doSomething()。当在头对象上调用 doSomething() 时,它要么做某事然后 returns 要么它的 doSomething() 调用下一个对象 doSomething() 等等,直到完成(或不完成!)。这更像你的例子,除了在你的情况下你手动尝试注入数组中的每个回调直到一个成功。
因此,您的示例看起来很像责任链策略 "intent" 的实施。
请注意,各种模式之间有很多相似之处,责任链、装饰器和组合都使用 link 节点对象列表来完成它们的工作。他们的意图不同,但很容易假设任何模式都是任何其他模式的退化版本。一棵树(复合)是一个 linked 列表,其中每个节点只有一个子节点(装饰器和链)。
指出模式通常涉及 OOP,而您的示例是根据回调来表述的。因此,如果您在评论中指出您正在遵循链模式,代码审阅者可能会寻找传统的 OOP 实现并感到困惑。但如前所述,您的代码完成了预期的工作,但在没有限定注释的情况下将其标记为链模式并不是 100% 清楚。
假设我已经看到 FallbackCompositeService
客户端对象使用它来获得具有回退机制的结果。
它使用 doSomething()
.
FallbackServiceInterface
我们有一个提供服务的 DI 容器,它是用一系列具体的回退策略实例化的(这里是伪PHP示例):
new FallbackCompositeService([
new Rule1FallbackService(),
new Rule2FallbackService(),
...
])
每个回退服务也实现 FallbackServiceInterface
,因此它们也 doSomething()
。
当我们调用 $result = $fallbackCompositeService->doSomething()
时,该服务循环通过其子服务调用相同的方法,第一个非空规则响应 "wins" 并返回。
问题是:
- 此实现是复合模式的 "degenerate" 版本(因此得名)吗?
- 或者它是责任链的"degenerate"版本(其中
nextHandler()
指针被简化为通过数组的迭代)? - 或什么 else/undefined/both/whatever...?它的潜在缺点是什么?
复合模式设想创建一个包含复合节点和叶节点的树结构——例如由表达式解析器生成的树结构。所有节点都具有相同的接口并包含它们自己的 evaluate() 实现。当在头节点上调用 evaluate() 时,所有节点都将提供最终答案的一部分(按照树遍历规定的正确顺序 - 假设解析器知道它在做什么!)。这与您的示例不同,您的示例在一个节点完成其工作时处理停止。
责任链设想了一个 linked 对象列表 - 每个对象都实现相同的接口,例如 doSomething()。当在头对象上调用 doSomething() 时,它要么做某事然后 returns 要么它的 doSomething() 调用下一个对象 doSomething() 等等,直到完成(或不完成!)。这更像你的例子,除了在你的情况下你手动尝试注入数组中的每个回调直到一个成功。
因此,您的示例看起来很像责任链策略 "intent" 的实施。
请注意,各种模式之间有很多相似之处,责任链、装饰器和组合都使用 link 节点对象列表来完成它们的工作。他们的意图不同,但很容易假设任何模式都是任何其他模式的退化版本。一棵树(复合)是一个 linked 列表,其中每个节点只有一个子节点(装饰器和链)。
指出模式通常涉及 OOP,而您的示例是根据回调来表述的。因此,如果您在评论中指出您正在遵循链模式,代码审阅者可能会寻找传统的 OOP 实现并感到困惑。但如前所述,您的代码完成了预期的工作,但在没有限定注释的情况下将其标记为链模式并不是 100% 清楚。