C ++:多个策略互相调用

时间:2011-11-30 12:59:00

标签: c++ templates metaprogramming policy

对于基于策略的类设计,我需要一些策略来调用其他策略中的函数:

struct PolicyA {
  void foo() {
    // ...
  }
};

struct PolicyB {
  void bar() {
    // Need to call foo() here
  }
};

template <class A, class B> MyClass : A, B {};

我看到的两个选项是:

  • MyClass<A, B>传递给PolicyAPolicyB作为模板参数,并执行dynamic_cast<MyClass<A, B>*>(this)->foo();之类的操作。然而,这可能很容易变得非常复杂(特别是如果它不仅B调用A而且还有另一种方式)。
  • 为每个策略都有一个基类,其中所有函数都声明为纯虚函数。当其中一个函数需要自己的模板参数时,这会失败,因为虚拟模板函数是不可能的。

这应该是一个常见的问题,但我没有找到任何东西。我猜可能有一些提升魔法或其他东西。你会如何解决这个问题?

修改:另请参阅后续内容here

1 个答案:

答案 0 :(得分:1)

为什么不PolicyB封装PolicyA并根据需要调用它? PolicyB显然知道PolicyA - 不需要基类或继承。

似乎所有Policy实现都有一些常见的apply方法,外部呼叫者可以同意这些方法吗?

编辑:

是的,所以如果不仅仅是一个特定的Policy实现需要访问另一个的简单案例,你应该专注于为Policy创建一个单独的接口 - 甚至可能是Rule类组合在一起形成一个特定的Policy - 参见规范模式。

class Rule {
    allows(Foo foo);
}

class Policy {
    Rule rule = new NotNullRule().and(someOtherRule);

    void applyTo(Foo foo) {
        if (rule.allows(foo)) {
            return foo;
        }
        foo.disable();
    }
}

根据需要调用它们ConditionRuleSpecification - 它们对于以不依赖于它们的方式组合逻辑片段非常有用。然后,当有人在看政策A时,他们可以清楚地看到管理其行为的规则/条件,客观化。

一旦实施了策略实施,如果需要对某些内容强制实施多个策略,则可以再次使用复合模式,以便外部类只能看到Policy接口。但同样,您有一个明确的“命名”策略,而不仅仅是交叉调用函数。