访问者模式-Visitor

名称:

    访问者模式(Visitor Pattern)-对象行为模式

 

问题:

    The Visitor pattern provides a maintainable, easy way to represent an operation to be performed on the elements of an object structure. 
The Visitor pattern lets you define a new operation without changing the classes of the elements on which it operates.

    表示一个作用于某对象结构中各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

 

适用性:

    1、一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖其具体类的操作。

    2、需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作“污染”这些对象的类。

    3、定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。

 

协作:

    -一个使用Vistor模式的客户必须创建一个ConcreteVistor对象,然后遍历该对象结构,并用该访问者访问每一个元素。

    -当一个元素被访问时,它调用对应于它的类的Visitor的操作。

 

优点和缺点:

    1、访问者模式使得易于增加新的操作。

    2、访问者集中相关的操作而分离无关的操作。

    3、增加新的ConcreteElement类很困难。

    4、通过类层次进行访问。

    5、累计状态。

    6、破坏封装。

解决方案:

    

1、 模式的参与者

    1、Visitor

    -为该对象结构中ConcreteElement的每一个类声明一个Visit操作。该操作的名字和特征标识类发送Visit请求给该访问者的那个类。这使得访问者可以确定正被访问元素的具体的类。

这样访问者就可以通过该元素的特定接口直接访问它。

    2、ConcreteVistor

    -实现每个由Visitor声明的操作。每个操作实现本算法的一部分,而该算法片段乃是对英语结构中对象的类。ConcreteVistor为该算法提供了上下文并存储它的局部状态。这一状态常常在遍历该结构的过程中累积结果。

    3、Element

    -定义一个Accept操作,它以一个访问者为参数。

   4、ConcreteElement

    -实现Accept操作,该操作以一个访问者为参数。

    5、ObjectStructure

    -能枚举它的元素。

    -可以提供一个高层的接口以允许该访问者访问它的元素。

   -可以是一个复合或是一个集合,如一个列表或一个无序集合。

 

2.实现方式

    

interface Visitor
{
    void visit(ConcreteElementA element);
    void visit(ConcreteElementB element);
}
class ConcreteVisitorA implements Visitor
{
    public void visit(ConcreteElementA element)
    {
        System.out.println("A visit "+element.operationA());
    }
    public void visit(ConcreteElementB element)
    {
        System.out.println("A visit "+element.operationB());
    }
}
class ConcreteVisitorB implements Visitor
{
    public void visit(ConcreteElementA element)
    {
        System.out.println("B visit "+element.operationA());
    }
    public void visit(ConcreteElementB element)
    {
        System.out.println("B visit "+element.operationB());
    }
}
interface Element
{
    void accept(Visitor visitor);
}
class ConcreteElementA implements Element
{
    public void accept(Visitor visitor)
    {
        visitor.visit(this);
    }
    public String operationA()
    {
        return "opration A ";
    }
}
class ConcreteElementB implements Element
{
    public void accept(Visitor visitor)
    {
        visitor.visit(this);
    }
    public String operationB()
    {
        return "opration B ";
    }
}
class ObjectStructure
{   
    private List<Element> list=new ArrayList<Element>();   
    public void accept(Visitor visitor)
    {
        Iterator<Element> i=list.iterator();
        while(i.hasNext())
        {
            ((Element) i.next()).accept(visitor);
        }      
    }
    public void add(Element element)
    {
        list.add(element);
    }
    public void remove(Element element)
    {
        list.remove(element);
    }
}

 

参考资料

《设计模式:可复用面向对象软件的基础》

posted @ 2020-07-01 17:29  diameter  阅读(128)  评论(0编辑  收藏  举报