我目前有两个访问者都正常工作。
#include <iostream>
#include <vector>
struct VisitorA
{
void DoSomething(){}
};
struct VisitorB
{
void DoSomething(){}
};
template <typename TVisitor>
static void RunAlgorithm(TVisitor& visitor);
int main()
{
VisitorA visitorA;
VisitorB visitorB;
RunAlgorithm(visitorA);
RunAlgorithm(visitorB);
}
template <typename TVisitor>
void RunAlgorithm(TVisitor& visitor)
{
visitor.DoSomething();
}
现在我想在算法中应用两个访问者。我见过一个“复合”访问者,它存储了多个访问者并简单地将呼叫转发给每个访问者。要做到这一点,似乎我必须创建一个“ParentVisitor”类并从中派生出来,这样我才能将ParentVisitor *存储在容器中:
#include <iostream>
#include <vector>
struct VisitorParent
{
void DoSomething(){}
};
struct VisitorA : public VisitorParent
{
void DoSomething(){}
};
struct VisitorB : public VisitorParent
{
void DoSomething(){}
};
struct VisitorComposite : public VisitorParent
{
void DoSomething()
{
for(unsigned int i = 0; i < Visitors.size(); ++i)
{
Visitors[i]->DoSomething();
}
}
std::vector<VisitorParent*> Visitors;
};
static void RunAlgorithm(VisitorParent& visitor);
int main()
{
// VisitorA visitor;
// RunAlgorithm(visitor);
VisitorA visitorA;
VisitorB visitorB;
VisitorComposite visitorComposite;
visitorComposite.Visitors.push_back(&visitorA);
visitorComposite.Visitors.push_back(&visitorB);
RunAlgorithm(visitorComposite);
}
void RunAlgorithm(VisitorParent& visitor)
{
visitor.DoSomething();
}
这样做的问题是,如果访问者有一些重复的功能,它将执行两次。我想把重复的代码移到VisitorParent,但是我不知道如何说“只为其中一个访问者运行父代码,而对于重复的部分只运行其余的代码”。这似乎是“手动” - 是否有更好的机制来应用两个(或更多)访问者?
答案 0 :(得分:0)
在我看来,除了抽象基础访问者类之外,您实际上总共需要四个具体访问者:
然后原始访问者A的角色通过与uniqueA组成共同来处理,访问者B的角色通过与uniqueB组成共同来处理,并且组合操作通过组成common,uniqueA和uniqueB来处理。
重复数据删除可以在合成器的工厂函数中完成,但您可能不希望在合成器类中“烘焙”重复数据删除,以保持更多的灵活性。
答案 1 :(得分:0)
使用访问者模式,如果你运行它,你真的不希望任何“破坏”。所以当你运行两次它应该可以工作。 是否你运行两次是一个比访问者更高级别的关注,所以它不应该影响访问者的设计。
因此,手册在这种情况下可能很好。
复合材料的作用可能应该是一个控制器。它可能知道,如果一个访问者成功,另一个访问者也不适合运行。向访问者添加返回值将为复合提供控制运行所需的反馈。控制器关注的是运行什么,访客保持愚蠢。