23种设计模式【Java】解析 - 访问者模式

访问者模式

目的

为一个对象结构(比如组合结构)增加新能力。

类图

角色

  • Visitor: 访问者。为每一个 ConcreteElement 声明一个 visit 操作
  • ConcreteVisitor: 具体访问者。存储遍历过程中的累计结果
  • ObjectStructure: 对象结构。可以是组合结构,或者是一个集合。
  • Element:抽象元素。抽象元素一般是抽象类或者接口,它定义一个accept()方法,该方法通常以一个抽象访问者作为参数。
  • ConcreteElement:具体元素。具体元素实现了accept()方法,在accept()方法中调用访问者的访问方法以便完成对一个元素的操作。
23种设计模式【Java】解析 - 访问者模式_第1张图片

实现

访问者

interface Visitor {
        public void visit(ConcreteElement1 el1);
        public void visit(ConcreteElement2 el2);
}

具体访问者

class ConcreteVisitor1 implements Visitor {

       @Override
       public void visit(ConcreteElement1 el1) {
           el1.doSomething();
       }

       @Override
       public void visit(ConcreteElement2 el2) {
           el2.doSomething();
       }
 }

class ConcreteVisitor2 implements Visitor {

       @Override
       public void visit(ConcreteElement1 el1) {
           el1.doSomething();
       }

       @Override
       public void visit(ConcreteElement2 el2) {
           el2.doSomething();
       }
 }

抽象元素

abstract class Element {
        public abstract void accept(IVisitor visitor);
        public abstract void doSomething();
    }

具体元素

 class ConcreteElement1 extends Element {
        public void doSomething(){
            ...
        }

        public void accept(Visitor visitor) {
            visitor.visit(this);
        }
 }
 class ConcreteElement2 extends Element {
        public void doSomething(){
            ...
        }

        public void accept(Visitor visitor) {
            visitor.visit(this);
        }
 }

对象结构

public class ObjectStruture {
    
    private List<Element> list = Lists.newArrayList();

    public void addElement(Element element){
        list.add(element);
    }

    public void accept(ElementVisitor visitor) {
        for (Element elem : list) {
            elem.accept(visitor);
        }
    }
    
}

调用类

 public class Client {
     public static void main(String[] args){
        ObjectStruture structure = new ObjectStruture();
        structure.addElement(new ConcreteElement1());
        structure.addElement(new ConcreteElement2());

        structure.accept(new ConcreteVisitor1());
        structure.accept(new ConcreteVisitor2());
     }
 }

优缺点

优点

  1. 符合单一职责原则。
  2. 优秀的扩展性。
  3. 灵活性。

缺点

  1. 具体元素对访问者公布细节,违反了迪米特原则。
  2. 具体元素变更比较困难。
  3. 违反了依赖倒置原则,依赖了具体类,没有依赖抽象。

使用场景

  1. 对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。
  2. 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。

JDK 中的使用

  • javax.lang.model.element.Element and javax.lang.model.element.ElementVisitor
  • javax.lang.model.type.TypeMirror and javax.lang.model.type.TypeVisitor

你可能感兴趣的:(设计模式,设计模式)