多个处理程序中只有一个处理程序应根据专业化进行操作的模式
我正在尝试重写一些代码以打破一些耦合问题并使将来更容易修改。
现在,我在基类中有一个静态工厂方法,它根据情况选择适当的实现。该决定基于专业化程度:
虽然 A 型和 B 型都可以处理这种情况,但 B 型是针对这种情况专门设计的,并且是正确的选择。
因此,基类与所有实现紧密耦合,并且在创建新的专用实现时必须重写此方法。
我正在考虑使用 责任链 模式来打破这种耦合。但是,我找不到确保执行最合格的实现的方法。如果我将其交给实现来做出此决定,我不能保证它们将按专业化顺序进行查询,而不会遇到相同的耦合问题。
有没有任何模式或方法来处理这样的情况?(我最好的猜测会阻碍部署;我会把它放在我的后口袋里,以免每个人都说“是的,这是唯一的方法!” ”)
I'm trying to rewrite some code to break some coupling issues and make it easier to modify in the future.
Right now, I have a static factory method in a base class that, depending on the situation, picks an appropriate implementation. The decision is based on degrees of specialization:
While types A and B both can handle this, B was designed specifically for this situation and is the correct choice.
The base class is therefore intimately coupled with all implementations and this method must be rewritten when new specialized implementations are created.
I'm thinking about using the Chain of Responsibility pattern to break this coupling. However, I cannot see a way of ensuring that the most qualified implementation executes. If I give it over to the implementations to make this determination, I cannot guarantee they will be queried in order of specialization without encountering the same coupling issues.
Are there any patterns or methods for handling situations like this? (My best guess would hinder deployment; I'll keep it in my back pocket lest everybody say "yeah, that's the only way to do it!")
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果您有办法量化我们的实现如何处理特定情况,您可以使用责任链的变体。
各个实现可以提供其处理给定输入集的能力的量化排名,并且您可以使用此排名来选择要使用的“最佳”实现。
然而,这不一定是一个伟大的设计——它为各个实现提供了很大的信任,并要求他们“诚实”地了解自己处理特定情况的能力。仍然有可能遇到多个实现报告相同值的情况,在这种情况下您需要选择某种选择方法。
If you have a way to quantify how we an implementation can handle a specific situation, you could use a variation of Chain of Responsibility.
The individual implementations could provide a quantified ranking of their ability to handle a given set of inputs, and you could use this ranking to choose the "best" implementation to use.
However, this is not necessarily a great design - it provides a lot of trust to the individual implementations, and requires them to be "honest" about how well they can handle a specific situation. It's also still possible to get into a situation where multiple implementations report the same value, in which can you need to choose some means of picking.
如果您可以为每种情况定义某种正确的排序函数,您可以让每个类注册其自身以及特定于类型的工厂,并基于此进行排序:
我能想到的唯一问题是比较将是不平凡的。对于任何 CaseInfo,它必须唯一地选择一个最佳匹配。诀窍是选择“任何其他”位。
If you can define some kind of proper ordering function for each case you could have each class register its self along with a type specific factory and sort based on that:
The only issue I can think of is that Compare will be non-trivial. For any CaseInfo, it must uniquely select a best match. The trick will be selecting the "Anything else" bit.
该解决方案可能是责任链和访问者模式的混合体。访问者可以抽象出一些常见的行为方面。
The solution might a hybrid of chain of responsibility and a visitor pattern. the visitor can abstract a few of the common behavioral aspects.
您需要根据一些运行时数据从许多可用的实现中创建一个特定的实现 - 这听起来像抽象工厂模式< /a>.
You need to create one particular implementation from the many available based on some runtime data - that sounds like the Abstract Factory pattern.
我不确定责任链是否可以这样建模。责任链的处理程序只能做两件事。处理请求或将其传递给下一个处理程序。它不知道下一个处理程序是哪个处理程序,也不知道谁应该处理该请求,它只知道它不能。
您的处理人员需要更有选择性。如果您有一个处理程序要处理 IE 窗口,另一个处理程序要处理 Java 应用程序,那么这两个处理程序需要能够检测它们正在处理的窗口类型。 IE 处理程序检查窗口是否是 IE,如果不是,则通过它,它不关心它是否在其他地方处理,它只知道它无法处理它。
我的建议是,创建仅处理 1 种窗口类型的特定处理程序。创建 1 个通用处理程序。然后对处理程序进行排序,以便通用处理程序位于最后。任何专用处理程序将首先尝试运行它,如果没有找到,通用处理程序将处理该请求。
如果您确实想做您的建议,那么您可以多次传递给处理程序。第 1 遍只有非常特殊的窗口才会被捕获。通过 2 个不太专业的窗口被捕获。等等,直到你厌倦了传球。然而,对我来说......我说,不要试图用 1 个处理程序做太多事情。如果每个处理程序负责 1 个窗口,那么顺序并不重要,它们将始终处理正确的窗口类型。任何未知的窗口都将被通用处理程序捕获。
I'm not sure Chain of Responsibility can be modeled like this. The handlers for chain of responsibility can only do 2 things. Process the request or pass it to the next handler. It doesn't know which handler is next or who's should process the request it only knows that it cannot.
Your handlers need to be more selective. If you have a handler that you want to handle IE windows and one to handle Java App then the two handlers need to be able to detect what type of window they are handling. The IE handler checks if the window is IE if not it passes it, it doesn't care if it gets handled somewhere else, it just knows that it can't handle it.
My suggestion, make specific handlers that only handle 1 window type. Make 1 generic handler. Then order the handlers so the generic handler is last. Any specialized handlers will attempt to run it first, if none are found the generic handler will process the request.
If you really wanted to do what your suggesting then you can make multiple passes to the handlers. Pass 1 only very specialized windows get caught. Pass 2 less specialized windows get caught. Etc etc until you're tired of making passes. However, for me... I say, don't try to do to much with 1 handler. If each handler is responsible for 1 window then the order doesn't matter, they will always handle the correct window type. Any unknown windows will be caught by the generic handler.