对于基于策略的类设计,我需要一些策略来调用其他策略中的函数:
struct PolicyA {
void foo() {
// ...
}
};
struct PolicyB {
void bar() {
// Need to call foo() here
}
};
template <class A, class B> MyClass : A, B {};
我看到的两个选项是:
MyClass<A, B>
传递给PolicyA
和PolicyB
作为模板参数,并执行dynamic_cast<MyClass<A, B>*>(this)->foo();
之类的操作。然而,这可能很容易变得非常复杂(特别是如果它不仅B
调用A
而且还有另一种方式)。这应该是一个常见的问题,但我没有找到任何东西。我猜可能有一些提升魔法或其他东西。你会如何解决这个问题?
修改:另请参阅后续内容here。
答案 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();
}
}
根据需要调用它们Condition
,Rule
,Specification
- 它们对于以不依赖于它们的方式组合逻辑片段非常有用。然后,当有人在看政策A时,他们可以清楚地看到管理其行为的规则/条件,客观化。
一旦实施了策略实施,如果需要对某些内容强制实施多个策略,则可以再次使用复合模式,以便外部类只能看到Policy
接口。但同样,您有一个明确的“命名”策略,而不仅仅是交叉调用函数。