程序员必备——2020 java进阶学习笔记:java中介者模式(mediator)

可紊 提交于 2020-02-27 05:11:36

简介

访问者模式(VisitorPattern),顾名思义使用了这个模式后就可以在不修改已有程序结构的前提下,通过添加额外的访问者来完成对已有代码功能的提升,它属于行为模式。访问者模式的目的是封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变。
其主要目的是将数据结构与数据操作分离。

访问者模式可以说是设计模式中最难以理解的一个模式,因为相比其它模式而言,它过于”绕“了。但是我们可以通过生活中的一些例子来理解它,比如家里来了客人,客人就是访问者,他可以做一些事情,但是又不能做全部的事情; 又或者说去网吧上网的小明,小明也是访问者,他可以在网吧玩游戏、看视频、听音乐等等,但是不能破坏网吧中的设备等等。按照这么理解,我们大概就可以知道访问者模式主要是做什么了。

访问者模式主要由这五个角色组成,抽象访问者(Visitor)、具体访问者(ConcreteVisitor)、抽象节点(Node)、具体节点(ConcreteNode)和结构对象(ObjectStructure)。

抽象访问者(Visitor)角色:声明了一个或者多个方法操作,形成所有的具体访问者角色必须实现的接口。
具体访问者(ConcreteVisitor)角色:实现抽象访问者所声明的接口,也就是抽象访问者所声明的各个访问操作。
抽象节点(Node)角色:声明一个接受操作,接受一个访问者对象作为一个参数。
具体节点(ConcreteNode)角色:实现了抽象节点所规定的接受操作。
结构对象(ObjectStructure)角色:有如下的责任,可以遍历结构中的所有元素。

示例图如下:

在这里插入图片描述

这里为了方便理解,我们使用一个简单的示例来加以说明。
图书馆有一台电脑,有两个账户,其中一个是管理员的账户,拥有所有权限,但是设置了密码;另一个账户是不需要密码,但是只能玩游戏和看图片。张三和李四先后使用了这台电脑,那么他们就可以当作是访问者。
那么我们便可以根据这里例子来使用访问者模式进行开发,首先定义一个抽象的访问者,拥有玩游戏和看图片的方法;然后再定义一个抽象节点电脑,接受这个请求。
那么这个抽象类的代码如下:


interface Visitor {
   void visit(Games games);
   void visit(Photos photos);
}

interface Computer {
   void accept(Visitor visitor);
}

定义好该抽象类之后,我们需要设计不同的访问者对节点进行不同的处理。并且需要设计具体节点类实现刚刚抽象节点的方法。

那么代码如下:

class ZhangSan implements Visitor {
   @Override
   public void visit(Games games) {
       games.play();
   }

   @Override
   public void visit(Photos photos) {
       photos.watch();
   }
}

class LiSi implements Visitor {
   @Override
   public void visit(Games games) {
       games.play();
   }
   @Override
   public void visit(Photos photos) {
       photos.watch();
   }
}

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

   public void play() {
       System.out.println("play lol");
   }
}

class Photos implements Computer {
   @Override
   public void accept(Visitor visitor) {
       visitor.visit(this);
   }
   
   public void watch() {
       System.out.println("watch scenery photo");
   }
}

最后我们还需要定义一个结构对象角色,提供一个的接口并允许该访问者进行访问,它可以对这些角色进行增加、修改或删除等操作和遍历。
代码如下:

class ObjectStructure {

    private List<Computer> computers = new ArrayList<Computer>();

    public void action(Visitor visitor) {
        computers.forEach(c -> {
            c.accept(visitor);
        });
    }
    public void add(Computer computer) {
        computers.add(computer);
    }
}
编写好之后,那么我们来进行测试。
测试代码如下:

public static void main(String[] args) {
       // 创建一个结构对象
       ObjectStructure os = new ObjectStructure();
       // 给结构增加一个节点
       os.add(new Games());
       // 给结构增加一个节点
       os.add(new Photos());
       // 创建一个访问者
       Visitor visitor = new ZhangSan();
       os.action(visitor);

}

输出结果:

play lol
watch scenery photo

访问者模式优点:

扩展性好,可以在不修改对象结构中的元素的情况下,为对象结构中的元素添加新的功能;
符合单一职责原则,通过访问者将无关的行为分离,使职责单一;

访问者模式缺点:

违反了迪米特原则,因为具体元素对访问者公布细节;
违反了依赖倒置原则,依赖了具体类,没有依赖抽象;
对象结构变化困难,若对象结构发生了改变,访问者的接口和访问者的实现也都要发生相应的改变;

使用场景:

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

原文出处:
原文链接:https://blog.csdn.net/qazwsxpcm/article/details/83588888

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!