2017-09-16 83 views

回答

0

访客模式并不意味着修改对象的状态。相反,它的目的是实现特定功能

一个范例将增加计算树元素的功能,我在这个Case Study: Applied Design Patterns and Software Architecture中解释了一个例子。

CharacterVisitor保持总的计数值访问CustomCharacter类具有以下结构:

/** 
* Implements the Visitor pattern 
*/ 
class CharacterVisitor 
{ 
    private int count = 0; 

    void visitCharacter(CustomCharacter customCharacter) 
    { 
     count++; 
    } 

    public int getResult() 
    { 
     return count; 
    } 
} 

countCharacters()功能,它实现了访问者模式的逻辑:

/** 
* Counts the words in the text by using the Iterator and Visitor patterns. 
*/ 
int countCharacters() 
{ 
    CharacterVisitor characterVisitor = new CharacterVisitor(); 
    CharacterIterator characterIterator = 
      new CharacterIterator(editorController.getCompositeBuilder()); 
    characterIterator.first(); 
    while(!characterIterator.isDone()) 
    { 
     CustomCharacter customCharacter = characterIterator.getCurrent(); 
     customCharacter.accept(characterVisitor); 
     characterIterator.next(); 
    } 
    return characterVisitor.getResult(); 
} 

注在这个例子中我也实现了Iterator pattern。我在案例研究中详细介绍了更多细节。

你可以在这个github repository找到完整的代码,我在这里解释了传说中的​​书中提到的所有设计模式。

+1

如果遵循这个无根据的规则,编译器的许多操作将无法实现。 – EJP

+0

也许我在答案中需要强调的一个澄清就是alfasin的回答所提到的:“改变元素的内部状态并不是一个要求:可能是访问者会调用某些元素的方法来完成所有种类的行为“ –

+1

也许当你写'不想修改'你错了。 – EJP

1

在以下示例中,邮件程序是“元素”,“访问者”是传递到send()的lambda表达式。

正如你可以在这里看到的(在很多其他例子中)访问者可以通过修改元素的内部状态。也就是说,改变元素的内部状态并不是必须的:访问者可能会调用某些元素的方法来执行各种操作:将消息传递给另一个对象,运行计算并打印结果等

import java.util.function.Consumer; 

public class Main { 

    public static void main(String[] args) { 
     Mailer.send(mailer -> 
      mailer.from("[email protected]") 
        .to("[email protected]") 
        .body("what's up bud?") 
     ); 
    } 
} 


class Mailer { 

    String fromStr; 
    String toStr; 
    String bodyStr; 

    public Mailer from(String from) { 
     this.fromStr = from; 
     return this; 
    } 

    public Mailer to(String to) { 
     this.toStr = to; 
     return this; 
    } 

    public Mailer body(String body) { 
     this.bodyStr = body; 
     return this; 
    } 

    public static void send(Consumer<Mailer> loader) { 
     Mailer mailer = new Mailer(); 
     loader.accept(mailer); 
     System.out.println(mailer); 
     // ... send the email 
    } 

    @Override 
    public String toString() { 
     return "From: " + fromStr + "\n" + 
       "To: " + toStr + "\n" + 
       "Body: " + bodyStr; 
    } 
} 
3

我见过不改变物体参观访问者模式的所有实例

,据我了解的定义上Wikipedia给出的,它只是没有定义什么,游客可以与被访问对象做。

即使从Gang of Four(也在wiki文章)的定义不接触该主题:

表示待上的对象 结构的元件执行的操作。访客可以让你定义一个新的操作,而不需要改变其操作元素的类别。

所以我想说,访问者可以调用对象的任何访问方法它访问,因为这不是访问者模式的组成部分 - 访问者模式只是描述这个对象是如何做访问

+1

(And ...实际上,在访问的目的是在图表的节点上执行更改的情况下,我使用了访问者模式。) –

0

访问(对象)方法能够更新或修改它所访问的对象。也就是说,它只能更新或修改在该类上都是公共和非只读的字段或属性。或者,访问方法可以使用对象公开的方法来更新或修改对象。

相关问题