Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 访问者设计模式中的方法命名_Design Patterns - Fatal编程技术网

Design patterns 访问者设计模式中的方法命名

Design patterns 访问者设计模式中的方法命名,design-patterns,Design Patterns,下面是visitor设计模式的上下文/示例代码 public interface Visitable{ public void accept(Visitor v); } public class Book implements Visitable{ public void accept(Visitor v){ v.visit(this); } public void read() {} /** book stuff **/

下面是visitor设计模式的上下文/示例代码

public interface Visitable{
    public void accept(Visitor v);
}

public class Book implements Visitable{
    public void accept(Visitor v){
        v.visit(this);
    }
    public void read() {}
    /**
    book stuff
    **/
}
public class Movie implements Visitable{
    public void accept(Visitor v){
        v.visit(this);
    }
    public void watch() {}
    /**
    movie stuff
    **/
}

public interface Visitor{
    public void visit(Book b);
    public void visit(Movie m);
}

public class Person implements Visitor{
    public void visit(Book b){
        b.read();
    }
    public void visit(Movie m){
        m.watch();
    }
}
我的指导老师说,重载
visit
方法不是一个好主意,我应该为每个visit方法指定一个不同的名称,如下所示。我不相信这个想法。有人能解释一下重载
visit
方法的缺点吗

public interface Visitor{
    public void visitBook(Book b);
    public void visitMovie(Movie m);
}

public class Person implements Visitor{
    public void visitBook(Book b){
        b.read();
    }
    public void visitMovie(Movie m){
        m.watch();
    }
}

《四人帮》一书,又名《圣经》,是按照你的导师的建议来做的

Visitor类在C++中的声明如下:

class Visitor {
public:
    virtual void VisitElementA(ElementA*);
    virtual void VisitElementB(ElementB*);

    // and so on for other concrete elements
protected:
    Visitor();
};
案件结案


请看我在@vadya上面的回答:重载意味着方法做相同的事情,但在不同类型上支持相同的事情,而Visitor则不是这样

根据我的理解,访问者设计模式的目的是解决单一调度问题。
访客模式提供了双重分派方法。动态分派仅基于调用对象的类型,该类型只能使用重写而不是重载。 使用重载将使函数依赖于调用期间传递的参数,我们不希望在visitor中使用该参数

使用重载覆盖的整体概念是在访问者中实现双重调度机制

John Vlissides的书《模式孵化》(GOF作者之一,他的书有时被认为是设计模式的补充)解释了实现Visitor的两种方法的优点

他说使用不同变量名的原因是:

当存在resonalbe默认行为时,一个更重要的优势就出现了,并且子类往往只覆盖一些操作。当我们重载时,子类必须覆盖所有函数;否则,友好的C++编译器可能会抱怨,你的选择性重写隐藏了一个或多个基类操作。当我们给访客操作起不同的名字时,我们绕过了这个问题。然后子类可以重新定义操作的子集而不受惩罚。 -图案填充第36页


我也想知道这个问题的答案,因为我同意你的看法。我从未见过这样的实现。除了笨拙地阅读之外,我发现有反映您访问的抽象的方法名称是很奇怪的。参数已经涵盖了这一点。@Vidya然后放弃投票:DDone。让我们看看会发生什么。这背后的原因是什么?我可以在教科书中找到使用过载的例子,但这并不能回答我的问题。我想说,如果你认为“四人帮”是错误的,你需要提供理由。我通常尽量避免在类型为param的方法中提及类型,但我认为在这种情况下这是有意义的,因为访问者的整个想法是所有做任何事情的方法都在一个地方。我和下一个家伙一样喜欢Go4和设计模式的想法,但是,盲目地、虔诚地毫无疑问地接受某些东西,这在任何事情上都是一个坏主意。除此之外,OP并没有说Go4是“错误的”。他是在问为什么他的想法也行不通。这比黑白对错问题更加微妙。让我们不要忘记来自欧比万的伟大。是的,《星球大战》不是我选择的道德文本,但谢谢你。我认为你错了,op是说他认为他的教练和Go4是错的。除了op实际上从来没有用“错”这个词。他说他“不相信这个想法”。我不相信无脂牧场敷料的想法,但我也不会称之为“错”。您似乎推断的比您应该推断的要多。“动态分派仅基于调用对象的类型,该类型只能使用重写而不是重载”<不正确根据我的理解,动态调度机制是我们所说的运行时多态性,它在运行时得到解决,而重载是编译时绑定,如果您能给我提供一些示例来证明该语句是错误的,这将对我和改进该概念有很大帮助。谢谢,这听起来是个很好的论点。这是一个C++ C++特有的代码>特性/代码>,还是在OO语言(C,java)中的一般行为?我认为这是C++特定的行为。对于java,根据JLS§9.4.1.:在逐个签名的基础上重写方法<代码>例如,如果一个接口声明了两个同名的公共方法(§9.4.2),并且子接口重写了其中一个,则子接口仍然继承另一个方法