设计模式之旅23--访问者模式

2018-08-14  本文已影响66人  小楠总

1. 定义

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

访问者模式

2. 使用场景

3. 实现

抽象元素以及具体元素:

/**
 * 抽象元素
 * 接口或者抽象类,声明接受哪一类访问者访问,程序上是通过accept方法中的参数来定义的
 */
public abstract class Element {

    public String mCommonProperty;

    public Element(String commonProperty) {
        mCommonProperty = commonProperty;
    }

    public abstract void accept(Visitor visitor);
}

/**
 * 具体元素
 * 实现accept方法,通常是visitor.visit(this),基本上都形成了一种模式了
 */
public class ConcreteElement1 extends Element {

    public String mProperty1;

    public ConcreteElement1(String commonProperty, String property) {
        super(commonProperty);
        this.mProperty1 = property;
    }

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

}

public class ConcreteElement2 extends Element {

    public String mProperty2;

    public ConcreteElement2(String commonProperty, String property) {
        super(commonProperty);
        this.mProperty2 = property;
    }

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

}

抽象访问者以及具体访问者:

/**
 * 抽象访问者
 * 抽象类或者接口,声明访问者可以访问哪些元素,具体到程序中就是visit方法的参数定义哪些对象是可以被访问的
 */
public interface Visitor {
    void visit(ConcreteElement1 element);
    void visit(ConcreteElement2 element);
}

/**
 * 具体访问者
 * 影响访问者访问到一个类后该怎么干,要做什么事情。
 */
public class ConcreteVisitor1 implements Visitor {
    @Override
    public void visit(ConcreteElement1 element) {
        //注:这里的访问逻辑需要根据具体业务来定
        //一般来说,不同访问者对同一种元素类型有不同的访问方式
        System.out.println("ConcreteVisitor1:" + element.mCommonProperty);
    }

    @Override
    public void visit(ConcreteElement2 element) {
        System.out.println("ConcreteVisitor1:" + element.mCommonProperty);
    }
}

public class ConcreteVisitor2 implements Visitor {
    @Override
    public void visit(ConcreteElement1 element) {
        System.out.println("ConcreteVisitor2:" + element.mProperty1);
    }

    @Override
    public void visit(ConcreteElement2 element) {
        System.out.println("ConcreteVisitor2:" + element.mProperty2);
    }
}

场景类:

public class Client {

    public static void main(String[] args) {
        //这里的List充当了UML中的ObjectStruture——结构对象,又叫元素产生者,一般容纳在多个不同类、不同接口的容器,如List、Set、Map等。
        //在项目中,一般很少抽象出这个角色。
        List<Element> elements = new ArrayList<>();
        elements.add(new ConcreteElement1("A", "1"));
        elements.add(new ConcreteElement1("B", "2"));
        elements.add(new ConcreteElement2("C", "3"));
        elements.add(new ConcreteElement2("D", "4"));
        
        Visitor visitor1 = new ConcreteVisitor1();
        Visitor visitor2 = new ConcreteVisitor2();

        for (Element e : elements) {
            e.accept(visitor1);
        }

        System.out.println("-----------");

        for (Element e : elements) {
            e.accept(visitor2);
        }
    }
}

运行结果:

ConcreteVisitor1:A
ConcreteVisitor1:B
ConcreteVisitor1:C
ConcreteVisitor1:D
-----------
ConcreteVisitor2:1
ConcreteVisitor2:2
ConcreteVisitor2:3
ConcreteVisitor2:4

4. 优点

5. 缺点

上一篇 下一篇

猜你喜欢

热点阅读