JAVA设计模式——访问者模式

访问者模式是一种行为型设计模式。其思想是:通过封装一些施加于某种数据结构元素之上的操作,使得当这些操作改变时,数据结构可以保持不变

访问者模式涉及到5个角色:

  • 抽象访问者(Visitor):声明了一个或者多个方法,形成所有的具体访问者角色必须实现的接口。
  • 具体访问者(Concrete Visitor):实现抽象访问者所声明的方法。
  • 抽象节点(Node):声明一个接受方法,接受一个访问者对象作为一个参数。
  • 具体节点(Concrete Node):实现了抽象节点所声明的方法。
  • 结构对象(Object Structure):必须包含一个可以遍历结构中的所有元素的方法;如果需要,提供一个高层次的接口让访问者对象可以访问每一个元素;如果需要,可以设计成一个复合对象或者一个聚集。

结构图:
这里写图片描述
(图片来源于网络)

具体代码实现(与上面的结构图并非配套):

节点:

public interface Node {
    void accept(Visitor visitor); // 声明一个方法,接收一个访问者对象作为参数
}

public class NodeA implements Node {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    public void method() {
        System.out.println("this is Node A");
    }
}

public class NodeB implements Node {
    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

    public void method() {
        System.out.println("this is Node B");
    }
}

访问者:

// 抽象访问者,针对不同的节点对象声明不同的方法
public interface Visitor {
    void visit(NodeA node);
    void visit(NodeB node);
}

public class ConcreteVisitor implements Visitor {
    @Override
    public void visit(NodeA node) {
        node.method();
    }

    @Override
    public void visit(NodeB node) {
        node.method();
    }
}

结构对象:

public class Structure {
    private List<Node> nodes = new ArrayList<>();

    // 由访问者代替数据结构访问具体的实现逻辑
    public void action(Visitor visitor) {
        nodes.forEach(node -> node.accept(visitor)); // 遍历自身
    }

    public void add(Node node) {
        nodes.add(node);
    }
}

客户:

public class Client {
    public void method() {
        Structure structure = new Structure();
        structure.add(new NodeA());
        structure.add(new NodeB());
        structure.action(new ConcreteVisitor());
    }
}

// 测试
class VisitorTest {
    public static void main(String[] args) {
        Client client = new Client();
        client.method();
    }
}

运行结果:

this is Node A
this is Node B


这里有一个二次分派的概念:

首先在客户程序中将具体访问者模式作为参数传递给具体元素角色(节点)。这便完成了一次分派。

进入具体元素角色后,具体元素角色调用作为参数的具体访问者模式中的visitor方法,同时将自己(this)作为参数传递进去。具体访问者模式再根据参数的不同来选择方法来执行。这便完成了第二次分派。


总结

访问者模式实现的数据结构与具体功能的松耦合,能够在不修改对象结构中的元素的情况下,为对象结构中的元素添加新的功能。另外访问者模式可以分离无关的行为,把相关的行为封装在一起,构成一个访问者,这样每一个访问者的功能都比较单一。

相反,当数据结构的类改变,那么访问者和具体实现的类都要跟住改变。所以这种情况下,访问者模式就不适用了。另外,访问者角色要执行与元素(节点)角色相关的操作,就必须让元素(节点)角色将自己内部属性暴露出来,而这就意味着其它的对象也可以访问。这就破坏了元素角色的封装性。

总的来说,访问者模式这是一个巧妙而且复杂的模式,它的使用条件比较苛刻。当系统中存在着固定的数据结构,而有着不同的行为,那么访问者模式也许是个不错的选择。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值