访问者模式-将数据结构本身和数据报表操作解耦

访问者模式是一种设计模式,旨在将数据结构和在其上执行的操作分离。它定义了抽象访问者和元素接口,允许访问者对元素进行特定操作。模式包括抽象访问者、具体访问者、抽象元素和具体元素角色。通过元素的accept方法调用访问者的visit方法,实现对元素的操作。此模式在不修改元素类的情况下,方便地扩展对元素的操作,但增加新元素时可能需要修改访问者,这违反了开闭原则。访问者模式主要解决数据展示操作变化的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

访问者模式定义

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

访问者模式结构图

在这里插入图片描述

访问者模式角色介绍

抽象访问者:Vistor,抽象访问者为每一个具体元素类ConcreteElement声明一个访问操作,从参数类型可以清楚知道需要访问的具体元素的类型,具体访问者需要实现这些操作方法,定义对这些元素的访问操作。

具体访问者:ConcreteVisitor,具体访问者实现了由抽象访问者声明的操作,每一个操作用于访问一个具体元素。

抽象元素:Element,抽象元素一般是抽象类或者接口,它定义一个accept()方法,该方法通常以一个抽象访问者作为参数。

具体元素:ConcreteElement,具体元素实现了accept()方法,在accept()方法中调用访问者的访问方法以便完成对该元素的操作。

访问者模式结构代码

抽象访问者:

public interface Visitor {

    /**
     * 访问具体元素A
     * @param concreteElementA
     */
    void visit(ConcreteElementA concreteElementA);

    /**
     * 访问具体元素B
     * @param concreteElementB
     */
    void visit(ConcreteElementB concreteElementB);
}

具体访问者:

public class ConcreteVisitor implements Visitor {

    public void visit(ConcreteElementA concreteElementA) {
        System.out.println(concreteElementA.getAttribute() +"-"+concreteElementA.getA());
    }

    public void visit(ConcreteElementB concreteElementB) {
        System.out.println(concreteElementB.getAttribute() +"-"+concreteElementB.getB());
    }
}

抽象元素:

public interface Element {

    void accept(Visitor visitor);
}

具体元素A:

public class ConcreteElementA implements Element {
    private String attribute;

    private String a;

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

    public String getAttribute() {
        return attribute;
    }

    public void setAttribute(String attribute) {
        this.attribute = attribute;
    }

    public String getA() {
        return a;
    }

    public void setA(String a) {
        this.a = a;
    }
}

具体元素B:

public class ConcreteElementB implements Element {
    private String attribute;

    private String b;

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

    public String getAttribute() {
        return attribute;
    }

    public void setAttribute(String attribute) {
        this.attribute = attribute;
    }

    public String getB() {
        return b;
    }

    public void setB(String b) {
        this.b = b;
    }
}

客户端:

public class Client {

    public static void main(String[] args) {
        Visitor visitor = new ConcreteVisitor();
        List<Element> elements = loadElements();
        for (Element e:elements) {
            e.accept(visitor);
        }
    }

    private static List<Element> loadElements(){
        ConcreteElementA concreteElementA = new ConcreteElementA();
        concreteElementA.setA("A");
        concreteElementA.setAttribute("公共A");

        ConcreteElementB concreteElementB = new ConcreteElementB();
        concreteElementB.setB("B");
        concreteElementB.setAttribute("公共B");

        List<Element> elements = new ArrayList<Element>();
        elements.add(concreteElementA);
        elements.add(concreteElementB);

        return elements;
    }
}
访问者模式运行机制

元素对象针对抽象访问者编程,元素的accept方法入参为抽象访问者类型;

访问者针对具体元素编程,有多少个具体元素,就需要定义多少个visit方法,其入参为具体元素类型;

访问者模式具体执行过程如下:

(1) 调用具体元素类的accept(Visitor visitor)方法,并将Visitor子类对象作为其参数;

(2) 在具体元素类accept(Visitor visitor)方法内部调用传入的Visitor对象的visit()方法,如visit(ConcreteElementA elementA),将当前具体元素类对象(this)作为参数,如visitor.visit(this);

(3) 执行Visitor对象的visit()方法,通过入参的具体元素对象,实现对元素的访问操作。

因为元素针对抽象访问者编程,所以增加具体访问者对原程序无任何影响,符合开闭原则;访问者针对具体元素编程,如果增加元素,所有的访问者都需要增加对新元素的访问处理,此时不符合开闭原则。

访问者模式解决的核心问题

数据结构和数据所具有的属性是固定不变的,但数据展示操作可能随时改变,通过访问者模式,可以轻松实现变更数据展示形式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值