2

我正在尝试重写一些代码以解决一些耦合问题并使其更容易在将来修改。

现在,我在基类中有一个静态工厂方法,可以根据情况选择适当的实现。该决定基于专业化程度:

虽然类型 A 和 B 都可以处理这个问题,但 B 是专门为这种情况设计的,是正确的选择。

因此,基类与所有实现紧密耦合,并且在创建新的专用实现时必须重写此方法。

我正在考虑使用责任链模式来打破这种耦合。但是,我看不到确保执行最合格的实现的方法。如果我把它交给实现来做出这个决定,我不能保证它们会按专业化的顺序被查询而不会遇到相同的耦合问题。

有没有处理这种情况的模式或方法? (我最好的猜测会阻碍部署;我会把它放在我的后兜里,以免每个人都说“是的,这是唯一的方法!”)

4

5 回答 5

2

如果您有办法量化我们的实现如何处理特定情况,您可以使用责任链的变体。

各个实现可以提供其处理给定输入集的能力的量化排名,您可以使用此排名来选择要使用的“最佳”实现。

然而,这不一定是一个很好的设计——它为各个实现提供了很大的信任,并要求他们“诚实”地了解他们处理特定情况的能力。仍然可能会遇到多个实现报告相同值的情况,在这种情况下,您可能需要选择一些选择方式。

于 2010-10-11T16:49:03.073 回答
1

该解决方案可能是责任链和访问者模式的混合体。访问者可以抽象出一些常见的行为方面。

于 2010-10-26T21:20:36.377 回答
1

如果您可以为每种情况定义某种适当的排序函数,您可以让每个类注册其自身以及特定类型的工厂并基于此进行排序:

class Base;
class CaseInfo;

class TypeFactory {
 public:
  virtual Base MakeOne();

  //... Anything needed to implement Compare
}

// each derived type must inject a instance into AllTypes
dequeue<TypeFactory> AllTypes;

bool Compare(const TypeFactory&, const TypeFactory&, const CaseInfo&);
Base Best(const CaseInfo&);

我能想到的唯一问题是比较将是不平凡的。对于任何 CaseInfo,它必须唯一地选择一个最佳匹配。诀窍是选择“其他任何东西”位。

于 2010-10-26T16:02:50.577 回答
0

我不确定责任链可以像这样建模。责任链的处理程序只能做两件事。处理请求或将其传递给下一个处理程序。它不知道下一个处理程序是哪个处理程序,也不知道谁应该处理它只知道它不能处理的请求。

您的处理程序需要更具选择性。如果您有一个要处理 IE 窗口的处理程序和一个处理 Java App 的处理程序,那么这两个处理程序需要能够检测它们正在处理的窗口类型。IE 处理程序检查窗口是否是 IE,如果不是,它会通过它,它不关心它是否在其他地方处理,它只知道它无法处理它。

我的建议是制作仅处理 1 种窗口类型的特定处理程序。制作 1 个通用处理程序。然后对处理程序进行排序,以便通用处理程序位于最后。任何专门的处理程序都将首先尝试运行它,如果没有找到,通用处理程序将处理请求。

如果你真的想按照你的建议去做,那么你可以多次传递给处理程序。通过 1 只有非常专业的窗口才会被捕获。通过 2 个不太专业的窗口被抓住。等等,直到你厌倦了传球。然而,对我来说......我说,不要试图对 1 个处理程序做太多事情。如果每个处理程序负责 1 个窗口,那么顺序无关紧要,它们将始终处理正确的窗口类型。任何未知的窗口都将被通用处理程序捕获。

于 2010-10-26T21:00:44.110 回答
0

您需要根据一些运行时数据从许多可用的实现中创建一个特定的实现——这听起来像抽象工厂模式

于 2010-10-11T16:47:50.797 回答