gpt4 book ai didi

Java 的双重分发与 Visitor 模式实例详解

转载 作者:qq735679552 更新时间:2022-09-28 22:32:09 27 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章Java 的双重分发与 Visitor 模式实例详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

双重分发(double dispatch) 。

什么是双重分发?

谈起面向对象的程序设计时,常说起的面向对象的「多态」,其中关于多态,经常有一个说法是「父类引用指向子类对象」.

这种父类的引用指向子类对象的写法类似下面这种:

?
1
2
animal animal = new dog();
animal.bark();

另一种常用的形式是 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public class keeper {
   public void say(animal a) {
    system.out.println( "animal say" );
   }
   public void say(dog dog) {
    system.out.println( "dog say" );
   }
}
animal animal = new animal();
animal dog = new dog();
keeper keeper = new keeper();
keeper.say(animal);
keep.say(dog);

那上面的keeper调用两次say的时候,会输出什么内容呢?会调用到两个不同的方法吗?

实际上在这两次调用的时候,都会调用到say(animal a)这个方法。由于这些内容在编译期就能确实下来,这就是 java 的 静态分发.

Java 的双重分发与 Visitor 模式实例详解

从上面的图我们看到,对于两次调用生成的字节码,确实都指向了say(animal a)这个方法,运行时直接执行方法,输出了对应的内容.

那对应的animal.bark() 为什么最终会调用到 dog 类的方法?这是在运行时确定具体的方法接收者的类型并执行。这就是所谓的动态分发,在运行时确定具体的方法,实现面向对象的多态.

分发(dispatch) 。

分发就是指最终确定一个要执行的方法的过程.

对于 java 等静态语言来说,都是通过 单一分发(single dispatch)来进行的方法执行。 比如这样一行代码 。

dog.eat(new bone()) 。

最终执行要选择的eat方法,只会根据dog的具体类型选择到对应的方法,而传入的参数并不能影响到对应方法的选择,这种就是 single dispatch 。

为了让传入的真实参数,这里就是bone来真正起到作用,就需要用到double dispatch或者叫做multiple dispatch 。

也就是说最终决定调用方法是哪一个的,不仅仅是方法的接收者,还受参数类型的决定.

visitor 模式 。

在gof 的设计模式中,visitor 模式就使用到了double dispatch 达到了调用真实对象的目的.

对于visitor 模式,最常用的例子是树的遍历。比如在处理到节点和树叶时的方式有区别,此归通过 visitor 的双重分发,实现对于不同的 element ,执行不同的内容.

代码类似这样:

?
1
2
node.accept( new concreatevisitor());
leaf.accept( new concreatevisitor());

node 中的 accept方法,会将自己的真实类型再次传递回visitor 。

?
1
2
3
public void accept(visitor v) {
  v.visit( this );
}

此时,在visitor中,就能根据真实的类型来调用具体的方法,对应node 和 leaf 分别有类似这样的方法:

?
1
2
public void visit(node n);
public void visit(leaf l);

visitor 总结起来一般是包含 visitor 接口,在visitor 接口中,包含各个即将被访问的 element对象的处理逻辑。在 各个element 的具体实现中,再将自己的类型传递回visitor 进行二次分发,实现确切逻辑的调用。 在tomcat中的应用 。

visitor 在tomcat中也有应用,典型的是解析el表达式.

比如org.apache.el.parser.node 。

这个类中包含一个accept(nodevisitor visitor)方法 。

实际的 node 类型有很多,但在真实调用的这个时候,会通过 。

?
1
2
public void accept(nodevisitor visitor) throws exception {
   visitor.visit( this );

将真实类型传回visitor, vistor中会调用具体的方法,从而实现参数也能起到决定作用的功能.

?
1
2
3
4
5
6
7
public void visit(node node) throws elexception {
   if (node instanceof astfunction) {
    astfunction funcnode = (astfunction) node;
    method m = null ;
 
    } else if (xxx) {
  }

这里一般会声明多个visit方法,然后上面的visit(this)会直接定位到目标方法上。 以上就是 java 中的各类分发,以及 visitor这种模式通过模式的形式来实现双重分发的效果。希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的! 。

原文链接:http://zhuanlan.51cto.com/art/201807/578177.htm 。

最后此篇关于Java 的双重分发与 Visitor 模式实例详解的文章就讲到这里了,如果你想了解更多关于Java 的双重分发与 Visitor 模式实例详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com