美文网首页
访问者模式

访问者模式

作者: 那年23 | 来源:发表于2019-01-01 16:35 被阅读11次

概念

  封装某些作用于某种数据结构中各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。

角色

先上一张图:


UML

抽象访问者:抽象类或者接口,声明访问者可以访问哪些元素
访问者:实现抽象访问者所声明的方法,它影响到访问者访问到一个类后该干什么,要做什么事情。
抽象元素类:接口或者抽象类,声明接受哪一类访问者访问。
元素类:实现抽象元素类所声明的方法。
结构对象:一个元素的容器,一般包含一个容纳多个不同类、不同接口的容器,如List、Set、Map等。

上代码

  就模拟一下文件访问操作。

抽象访问者
/**
 * 
 * 抽象访问者类:申明可以访问哪些元素
 *
 */
public interface Visiter {
    void visit(DocA doca);
    
    void Visit(DocB docb);
}
访问者
/**
 * 具体的访问者
 *
 */
public class VisiterA implements Visiter {

    @Override
    public void visit(DocA doca) {
        System.out.println("DocA's content is:" + doca.readDoc());
    }

    @Override
    public void Visit(DocB docb) {
        System.out.println("DocB's content is:" + docb.readDoc());
    }

}

抽象元素类
/**
 * 
 * 抽象元素类:声明 接受何种类型的访问。
 *
 */
public abstract class Doc {
    public abstract void accept(Visiter visiter);
    public abstract String readDoc();
}
具体的元素类

  这里可以把readDoc方法交由Visiter实现。

/**
 * 
 * 具体的元素类A(ConcreteElement)
 *
 */
public class DocA extends Doc {

    //使用accept,代表只有指定的visiter才能访问。
    @Override
    public void accept(Visiter visiter) {
        visiter.visit(this);
    }

    @Override
    public String readDoc() {
        return "This is DocA";
    }

}
/**
 * 具体的元素类B(ConcreteElement)
 *
 */
public class DocB extends Doc{

    @Override
    public void accept(Visiter visiter) {
        visiter.Visit(this);
    }

    @Override
    public String readDoc() {
        return "This is DocB";
    }

}
结构对象
/**
 * 
 *文件袋:结构对象,容纳元素
 */
public class DocBag {
    private List<Doc> docs = new ArrayList<>();
    
    public List<Doc> getList(){
        if(docs.size()==0){
            docs.add(new DocA());
            docs.add(new DocB());
        }
        return docs;
    }

}
客户端测试类
public class VisitClient {
    public static void main(String[] args) {
        DocBag bags = new DocBag();
        List<Doc> docs = bags.getList();
        
        VisiterA visiter = new VisiterA();
        
        for(Doc doc:docs){
            doc.accept(visiter);
        }
    }
}
结果
The End

  看完代码就发现了,访问者模式主要将数据结构与数据操作分离。但是这样不符合迪米特原则。

优点:
  1、可扩展性比较好,灵活。元素类可以通过接受不同的访问者来实现对不同操作的扩展。
  2、符合单一职责原则。

缺点
   1、具体元素对访问者公布细节,违反了迪米特原则。
  2、因为访问者对应着具体元素的操作,所以添加元素的话需要修改很多地方。

相关文章

网友评论

      本文标题:访问者模式

      本文链接:https://www.haomeiwen.com/subject/ohinlqtx.html