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

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

作者: 程就人生 | 来源:发表于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