美文网首页
访问者模式,数据结构、操作的解耦?

访问者模式,数据结构、操作的解耦?

作者: 程就人生 | 来源:发表于2022-05-24 21:27 被阅读0次

    访问者模式,是谁来访问谁的,怎么访问的?

    访问者模式,能使用在什么业务场景下呢?

    访问者模式(Visitor Pattern),定义了一个作用于某对象结构中元素的操作,在不改变各元素的前提下,定义作用于这些元素的新操作。

    特点:将数据结构和数据操作分离开来。

    业务场景:解决稳定的数据结构和易变的操作耦合问题。

    在访问者模式中,有两种角色:访问者和被访问者。数据结构就是被访问者,再定义一个访问者来访问被访问者。

    访问者和被访问者之间的关系是怎样的呢,下面看UML类图:


    类图说明:图中有两组类,一组是元素接口IElement及两个子类ElmentoOne和ElementTwo,子类是接受访问者。另一组是访问者接口IVisitor及其子类访问者Visitor。元素接口IElement依赖了访问者接口IVisitor,访问者接口IVisitor又依赖了两个元素子类,具体被访问和访问操作则在其子类实现。

    从类图中可以看出来,它们之间的关系还是很复杂的,除了接口和子类的实现关系,还有元素接口对访问者接口的依赖,访问者接口对元素子类的依赖。

    下面看代码实现: 1.元素接口;

    /**
     * 1.元素接口
     * @author 程就人生
     * @Date
     */
    public interface IElement {
    
      /**
       * 接受访问者的访问
       * @return
       */
      public void accept(IVisitor visitor);
      
      /**
       * 被访问后的操作
       */
      public void doAction();
    }
    

    2.元素接口的子类;

    /**
     * 2.1 元素one,元素接口的实现类
     * @author 程就人生
     * @Date
     */
    public class ElementOne implements IElement {
    
      @Override
      public void accept(IVisitor visitor) {
        visitor.visit(this);
      }
    
      @Override
      public void doAction() {
        System.out.println("ElementOne 欢迎您的到访。");
      }
    }
    
    /**
     * 2.2 元素two,元素接口的实现类
     * @author 程就人生
     * @Date
     */
    public class ElementTwo implements IElement {
    
      @Override
      public void accept(IVisitor visitor) {
        visitor.visit(this);
      }
    
      @Override
      public void doAction() {
        System.out.println("ElementTwo 欢迎您的到访。");
      }
    }
    

    3.访问者接口;

    /**
     * 3. 访问者接口
     * @author 程就人生
     * @Date
     */
    public interface IVisitor {
    
      /**
       * 元素1的访问
       * @param e
       */
      public void visit(ElementOne e);
      
      /**
       * 元素2的访问
       * @param e
       */
      public void visit(ElementTwo e);
    }
    

    4.访问者接口的子类,具体的访问者;

    /**
     * 4. 访问者的实现类
     * @author 程就人生
     * @Date
     */
    public class Visitor implements IVisitor {
    
      @Override
      public void visit(ElementOne e) {
        System.out.println("Visitor访问了:" + e.getClass().getSimpleName());
      }
    
      @Override
      public void visit(ElementTwo e) {
        System.out.println("Visitor访问了:" + e.getClass().getSimpleName());
      }
    }
    

    5.测试代码;

    public static void main(String[] argo){
        // 创建元素1
        ElementOne one = new ElementOne();
        // 元素1同意访问者访问
        one.accept(new Visitor());
        one.doAction();
      }
    

    运行结果:

    Visitor访问了:ElementOne
    ElementOne 欢迎您的到访。
    

    这段代码的意思是:访问者要访问元素one和元素two,还不想破坏元素内部的数据结构和操作。通过设计一个访问者接口及其子类,进入被访问者内部,达到了访问被访问者的目的。以上便是访问者模式的简单实现。有没有反应过来,访问者是如何打印这一行文字的?关系奇妙吧?!

    如果又增加了一个访问者,那么是很容易扩展的,原来的代码都不需要动,只需扩展访问者接口即可。

    最后总结

    访问者模式,是对数据结构和数据操作的分离,适用于数据结构不变,但数据操作易变的场景。当然,被访问者和访问者之间的依赖关系是双向的,也是复杂的,这个是理解的重点。

    在你的项目中,有类似的业务场景吗?你是怎么处理的?还有优化的空间吗?衡量一下利弊,该怎么优化呢?

    相关文章

      网友评论

          本文标题:访问者模式,数据结构、操作的解耦?

          本文链接:https://www.haomeiwen.com/subject/xakburtx.html