Java-访问者-设计模式(二十)

说明

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

UML
在这里插入图片描述
角色:
Visitor 抽象访问者角色:为该对象结构中具体元素角色声明一个访问操作接口。该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色,这样访问者就可以通过该元素角色的特定接口直接访问它。
ConcreteVisitor.具体访问者角色:实现Visitor声明的接口。
Element: 定义一个接受访问操作(accept()),它以一个访问者(Visitor)作为参数。
ConcreteElement 具体元素:实现了抽象元素(Element)所定义的接受操作接口。
ObjectStructure 结构对象角色:这是使用访问者模式必备的角色。它具备以下特性:能枚举它的元素;可以提供一个高层接口以允许访问者访问它的元素;如有需要,可以设计成一个复合对象或者一个聚集(如一个列表或无序集合)。

代码

以《大话设计模式》中该模式的基本代码为例,代码如下。

Visitor,为该对象结构中具体元素角色声明一个访问操作接口。

/**
 * @author ctl
 * @date 2021/1/29
 */
public interface Visitor {

    void visitConcreteElementA(ConcreteElementA concreteElementA);

    void visitConcreteElementB(ConcreteElementB concreteElementB);
}

ConcreteVisitor1,具体访问者

/**
 * @author ctl
 * @date 2021/1/29
 */
public class ConcreteVisitor1 implements Visitor {

    @Override
    public void visitConcreteElementA(ConcreteElementA concreteElementA) {
        System.out.println(concreteElementA.getClass().getSimpleName() + "被"
                + this.getClass().getSimpleName() + "访问");
        concreteElementA.operationA();
    }

    @Override
    public void visitConcreteElementB(ConcreteElementB concreteElementB) {
        System.out.println(concreteElementB.getClass().getSimpleName() + "被"
                + this.getClass().getSimpleName() + "访问");
        concreteElementB.operationB();
    }
}

ConcreteVisitor2,具体访问者

/**
 * @author ctl
 * @date 2021/1/29
 */
public class ConcreteVisitor2 implements Visitor {

    @Override
    public void visitConcreteElementA(ConcreteElementA concreteElementA) {
        System.out.println(concreteElementA.getClass().getSimpleName() + "被"
                + this.getClass().getSimpleName() + "访问");
        concreteElementA.operationA();
    }

    @Override
    public void visitConcreteElementB(ConcreteElementB concreteElementB) {
        System.out.println(concreteElementB.getClass().getSimpleName() + "被"
                + this.getClass().getSimpleName() + "访问");
        concreteElementB.operationB();
    }
}

Element,定义一个accept操作,它以一个访问者为参数

/**
 * @author ctl
 * @date 2021/1/29
 */
public interface Element {

    void Accept(Visitor visitor);
}

ConcreteElementA,具体元素,实现accept操作

/**
 * @author ctl
 * @date 2021/1/29
 */
public class ConcreteElementA implements Element {

    // 处分利用双分派技术,实现处理于数据结构的分离
    @Override
    public void Accept(Visitor visitor) {
        visitor.visitConcreteElementA(this);
    }

    // 其他的相关方法
    public void operationA() {
        System.out.println("com.example.design.behavior.visitor.ConcreteElementA.operationA被调用");
    }
}

ConcreteElementB,具体元素,实现accept操作

/**
 * @author ctl
 * @date 2021/1/29
 */
public class ConcreteElementB implements Element {

    @Override
    public void Accept(Visitor visitor) {
        visitor.visitConcreteElementB(this);
    }

    public void operationB() {
        System.out.println("com.example.design.behavior.visitor.ConcreteElementB.operationB被调用");
    }
}

ObjectStructure 结构对象角色,这是使用访问者模式必备的角色,能枚举它的元素,可以提供一个高层接口以允许访问者访问它的元素。

/**
 * @author ctl
 * @date 2021/1/29
 */
public class ObjectStructure {

    private List<Element> elements = new ArrayList<>();

    public void attach(Element element) {
        elements.add(element);
    }

    public void detach(Element element) {
        elements.remove(element);
    }

    public void accept(Visitor visitor) {
        for (Element element : elements) {
            element.Accept(visitor);
        }
    }
}

测试类

/**
 * @author ctl
 * @date 2021/1/29
 */
public class VisitorMain {

    public static void main(String[] args) {
        ObjectStructure o = new ObjectStructure();
        o.attach(new ConcreteElementA());
        o.attach(new ConcreteElementB());

        ConcreteVisitor1 v1 = new ConcreteVisitor1();
        ConcreteVisitor2 v2 = new ConcreteVisitor2();

        o.accept(v1);
        o.accept(v2);
    }
}

结果
在这里插入图片描述
访问者模式可以说是最复杂和难以理解的一个设计模式,所以本次直接用了跟uml对应的代码来做示例。

总结

访问者模式适用于数据结构相对稳定的系统,它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由的演化。

访问者模式的优点是增加新的操作较容易,也就是增加一个新的访问者;而缺点就是增加新的数据结构变得困难了

“访问者模式的能力和复杂性是一把双刃剑,只有当你真正需要它的时候,才考虑使用它。有的程序员为了展示自己面向对象的能力或沉迷于模式当中,往往会误用这个模式,所以一定要好好理解它的适用性。” ————《大话设计模式》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值