访问者模式,是谁来访问谁的,怎么访问的?
访问者模式,能使用在什么业务场景下呢?
访问者模式(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,还不想破坏元素内部的数据结构和操作。通过设计一个访问者接口及其子类,进入被访问者内部,达到了访问被访问者的目的。以上便是访问者模式的简单实现。有没有反应过来,访问者是如何打印这一行文字的?关系奇妙吧?!
如果又增加了一个访问者,那么是很容易扩展的,原来的代码都不需要动,只需扩展访问者接口即可。
最后总结
访问者模式,是对数据结构和数据操作的分离,适用于数据结构不变,但数据操作易变的场景。当然,被访问者和访问者之间的依赖关系是双向的,也是复杂的,这个是理解的重点。
在你的项目中,有类似的业务场景吗?你是怎么处理的?还有优化的空间吗?衡量一下利弊,该怎么优化呢?
网友评论