OOAD作业---设计模式---访问者模式

来源:互联网 发布:知乎神经性耳鸣5年 编辑:程序博客网 时间:2024/04/30 03:42
访问者模式(Visitor)
===================
ps:这个是作业来的,还没写完这份文档,先post上来,反正也写完了多分派的一些重点内容。

访问者模式主要内容有看两点,第一个是访问对象结构(比如遍历一颗树上的对象节点什么的),第二个就是在单分派语言上实现二分派啦。在《设计模式》中的解释是,访问者模式可以让你在不改动原有对象结构(代码)的基础上给它们添加新方法。


照例来段原文,方便自己解释
> Represent an operation to be performed on the elements of an object
> structure. Visitor lets you define a new operation without changing the
> classes of the elements on which it operates.


栗子
-----


###多分派


假如你知道什么是多分派(multiple dispatch)可以跳过这一段。


我们来模拟一个动物吃食物的过程,先看下参战双方,动物这边有Cat和Dog,都是继承自Aninamal,并重写了其中的3个不同签名的eat方法。


```java
public class Animal {
    public void eat(Food food){
    }
    public void eat(Fish fish){
    }
    public void eat(Mutton mutton){
    }
}
public class Cat extends Animal{
    @Override
    public void eat(Food food){
    }
    @Override
    public void eat(Fish fish){
    }
    @Override
    public void eat(Mutton mutton){
    }
}
public class Dog extends Animal{
    @Override
    public void eat(Food food){
    }
    @Override
    public void eat(Fish fish){
    }
    @Override
    public void eat(Mutton mutton){
    }
}
```


下面是我们的食物类,有Fish,Mutton,继承自Food。
```java
public class Food{}
public class Mutton extends Food{}
public class Fish extends Food{}
```


大家都知道,java的多态(Polimorphism)是在运行时动态地根据具体对象来选择实际要调用哪个方法(Override)。另外需要提一下的是重写(Overload),重写是根据方法的不同参数来调用不同的方法,不过,jvm在预处理的时候实际上是把签名合并到方法名中去了,所以实际上是两个不同方法名的方法。


好了,我们开始先下面的测试代码
```java
Animal animal;
Food food;
Mutton mutton;


animal = new Dog();
food = new Fish();
mutton = new Mutton();


animal.eat(mutton);
animal.eat(food);
```


最后一条语句,根据我们了解到的java的多态性,我们知道这时的animal.eat方法一定是Dog里面重写的那个eat方法,这个毋庸置疑。
但是,dog里面重写了3个不同签名的eat方法,这时调用的是哪一个呢?没错,是eat(Food),而不是eat(Fish),虽然传给eat方法的确实是fish对象,虽然挂了个Food的外号。只有倒数第二条语句(animal.eat(mutton))才会用到Overload的福利,成功调用到了eat(Mutton)。
为毛?为毛?为毛?因为java是单分派语言,附带上一大票单分派战友(c#,c++,python)。
单分派的意思是,它只会去根据一条继承链来寻找合适的对象,java(以及大部分面向对象语言)中的实现是用在了调用的对象上面(这个是写死的),也就是发起调用的对象。
这就是为什么我们的animal可以成功地被辨识为dog,但是方法里面的参数中的food就不能在运行时被辨识为Fish。
那末这样子就很容易知道多分派语言是什么啦。看下面的老虎机图片,每个滚轴都代表一条继承链的话,那么单分派语言就只能有一个滚轴,而且是定死在那个位置滚(只对调用方法的对象进行分派),而多分派语言就像下面的老虎机,有好多个对象都可以动态地分派。
多分派语言比较有名的是(Common Lisp),哇,函数式编程语言,看起来就很高大上。


[老虎机图片]()


ps: java,c++中的单分派具体实现在这里没有分析,有兴趣可以看参考资料(),common lisp完全没看过,有时间再看下。有关多分派的内容,请看参考资料()。


###我们来模拟一个双分派

(未完待续)








0 0
原创粉丝点击