为什么要使用访客模式?

27 design-patterns visitor

重复:我应该何时使用访客设计模式

为什么有人想要使用访客模式?我读了几篇文章,但我没有得到什么.

如果我需要一个功能来收取定制,我可以使用

Custom.Accept(BillVisitor)
Run Code Online (Sandbox Code Playgroud)

或类似的东西

Bill(Customer)
Run Code Online (Sandbox Code Playgroud)

第二个不太复杂,Bill函数仍然与Customer类分开.那么我为什么要使用访客模式呢?

S.L*_*ott 49

当你有一个复杂的结构,即层次结构或其他不仅仅是线性的结构时,问题就出现了.当你不能简单地遍历结构时,访问者非常方便.

如果我有一个层次结构(或树),每个节点都有一个子列表.当我想将一个过程应用于树中的每个节点时,创建一个访问者是很愉快的.

然后,节点可以将访问者应用于自身及其每个子节点.过渡性地,每个孩子都做同样的事情(将访客应用于自己,然后应用于任何孩子).

访问者的这种使用非常好.

如果您拥有超简单的数据结构,则访问者不会添加大量值.

  • 值得一提的是,这个答案描述了[Hierarchical visitor pattern](http://en.wikipedia.org/wiki/Hierarchical_visitor_pattern),与实际(名称不详)[Visitor pattern](http://en.wikipedia)相对立. org/wiki/Visitor_pattern)它基本上允许你在不修改它们的情况下在现有类上添加新操作,如@ididak [下面](http://stackoverflow.com/a/362186/69809)的答案中所述.树遍历与此模式无关,尽管命名意味着它(种类). (2认同)

idi*_*dak 15

访问者模式是不直接支持多个调度的语言的攻击(C++和Java之类的语言仅支持基于对象的单一调度.CLOS支持多个调度).在这种情况下,如果您希望Bill和Customer都是多态的,那么您必须使用单一调度语言中的两个接口BillVisitor和Customer.例如:accept的实现通常是:

void accept(BillVisitor visitor) { visitor.bill(this); } // java syntax
Run Code Online (Sandbox Code Playgroud)

请注意,Customer#accept和BillVisitor#bill都可以被它们各自的子类覆盖,从而产生非常丰富的运行时行为组合,否则无法实现.它实际上是大多数其他人在此描述的替代封闭的超集,以将功能应用于复杂的数据结构.