我正在尝试为具有不同返回类型(string,signed int,unsigned int等)的方法的对象结构实现访问者模式.
现在,在对象层次结构中,我添加了一个带有以下签名的Accept方法(使用C++):
void Accept(Visitor *);
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚如何使用相同的接口(使用void返回类型),同时允许我的具体方法具有不同的返回类型.
我有一个AST,以通常的方式表示(抽象类型的节点树).我有几个遍历这个树的用例(一个优化器,它返回另一个AST; IR代码生成,它返回一个llvm::Value*;和一个调试分析器,它只是输出到stdout并且什么都不返回).
访问者感觉这是正确的方式,但访问者的每个用例的不同返回类型使得很难看到如何为此实现接口.我考虑过这个:
class Visitor;
class ASTNode {
public:
virtual void accept(Visitor *visitor);
};
class Visitor {
public:
virtual void visit(CallNode *node) = 0;
virtual void visit(BinExprNode *node) = 0;
// etc
};
Run Code Online (Sandbox Code Playgroud)
由于缺少返回值,每个Visitor实现都需要构建内部状态并提供result()具有合适返回类型的方法.然而,这很复杂,因为每次调用都visit()需要围绕被访问的表达式的某些上下文(即单独调用,或者它是否被用作二进制表达式的一部分?).对于像二进制表达式代码生成这样的事情来说,通过访问操作数的节点来收集返回值(我可以使用内部临时状态变量或其他类似的东西,但它感觉过度设计)并且难以推理(国家不断变化).
class OptimizingVisitor : public Visitor {
ASTNode *m_result;
public:
ASTNode *result() {
return m_result;
}
void setResult(ASTNode *node) {
m_result = node;
}
void visit(CallNode *node) {
node->left()->accept(this);
ASTNode *optimizedL = result();
node->right()->accept(this);
ASTNode *optimizedR = result();
setResult(new CallNode(optimizedL, optimizedR)); …Run Code Online (Sandbox Code Playgroud) 我使用Visitor设计模式来解决系统中的一个问题.作为参考如何实现它我使用DoFactory网站和这个YouTube视频.
在DoFactory示例中,访问者使用返回类型为"void"的方法,在YouTube视频中,作者使用"double".
为什么我问:
在向公司首席技术官提交解决方案之后,他接受称其为访客,但他声称如果访客不像GoF中所说的那样"无效",就像滥用真实的访客模式一样.
问题:
访客模式是否需要返回"无效"?
我的意思是为了成为"真实的访客模式",因为DoFactory(GoF)描述它,或者它可以是任何返回类型,仍然可以被称为"真实访客模式"?