Chinaunix首页 | 论坛 | 博客
  • 博客访问: 820879
  • 博文数量: 780
  • 博客积分: 7000
  • 博客等级: 少将
  • 技术积分: 5010
  • 用 户 组: 普通用户
  • 注册时间: 2008-09-12 09:11
文章分类

全部博文(780)

文章存档

2011年(1)

2008年(779)

我的朋友
最近访客

分类:

2008-09-12 09:14:52

一,访问者模式的角色:
抽象访问者:声明一个或者多个访问操作,形成所有的具体元素都要实现的接口
具体访问者:实现抽象访问者所声明的接口
抽象节点:声明一个接受操作,接受一个访问者对象作为参量
具体节点:实现了抽象元素所规定的接受操作
结构对象:遍历结构中的所有元素,类似List Set等
二,在什么情况下应当使用访问者模式
访问者模式应该用在被访问类结构比较稳定的时候,换言之系统很少出现增加新节点的
情况。因为访问者模式对开-闭原则的支持并不好,访问者模式允许在节点中加入方法,
是倾斜的开闭原则,类似抽象工厂。
三,访问者模式的缺点:
1,增加节点困难
2,破坏了封装
因为访问者模式的缺点和复杂性,很多设计师反对使用访问者模式。个人感觉应该在了解的
情况下考虑衡量选择.

静态分派,动态分派,多分派,单分派 -------------- visitor模式准备 
一,静态分派:
1,定义:发生在编译时期,分派根据静态类型信息发生,重载就是静态分派
2,什么是静态类型:变量被声明时的类型是静态类型
      什么是动态类型:变量所引用的对象的真实类型
3,有两个类,BlackCat ,WhiteCat都继承自Cat
如下调用
class Cat{}
class WhiteCat extends Cat{}
class BlackCat extends Cat{}
public class Person {
    public void feed(Cat cat){
        System.out.println("feed cat");
    }
    public void feed(WhiteCat cat){
        System.out.println("feed WhiteCat");
    }
    public void feed(BlackCat cat){
        System.out.println("feed BlackCat");
    }
    public static void main(String[] args) {
        Cat wc = new WhiteCat();
        Cat bc = new BlackCat();
        Person p = new Person();
        p.feed(wc);
        p.feed(bc);
    }

}
运行结果是:
feed cat
feed cat
这样的结果是因为重载是静态分派,在编译器执行的,取决于变量的声明类型,因为wc ,bc都是Cat所以调用的都是feed(Cat cat)的函数.
二,动态分派
1,定义:发生在运行期,动态分派,动态的置换掉某个方法。
还是上边类似的例子:
class Cat{
    public void eat(){
        System.out.println("cat eat");
    }
}
public class BlackCat extends Cat{
    public void eat(){
        System.out.println("black cat eat");
    }
    public static void main(String[] args){
        Cat cat = new BlackCat();
        cat.eat();
    }
}这个时候的结果是:
black cat eat
这样的结果是因为在执行期发生了向下转型,就是动态分派了。

三,单分派:
1,定义:根据一个宗量的类型进行方法的选择
四,多分派:
1,定义:根据多于一个宗量的类型对方法的选择
2,说明:多分派其实是一系列的单分派组成的,区别的地方就是这些但分派不能分割。
3, ,都是动态单分派,静态多分派语言
多分派的语言有:CLOS  Cecil


访问差异类型的集合类--visitor模式入门
访问差异类型的集合类--visitor模式入门
本文对应代码这里
一,问题提出
访问同一类型的集合类是我们最常见的事情了,我们工作中这样的代码太常见了。


1  Iterator ie  =  list.iterator();
2   while (ie.hasNext())  {
3     Person p  =  (Person)ie.next();
4     p.doWork();
5 } 

这种访问的特点是集合类中的对象是同一类对象Person,他们拥有功能的方法run,我们调用的恰好是这个共同的方法。
在大部份的情况下,这个是可以的,但在一些复杂的情况,如被访问者的继承结构复杂,被访问者的并不是同一类对象,
也就是说不是继承自同一个根类。方法名也并不相同。例如 GUI中的事件就是一个例子。
例如这样的问题,有如下类和方法:
类:PA ,方法:runPA();
类:PB ,方法:runPB();
类:PC ,方法:runPC();
类:PD ,方法:runPD();
类:PE ,方法:runPE();
有一个集合类List
List list = new ArrayList();
list.add(new PA());
list.add(new PB());
list.add(new PC());
list.add(new PD());
list.add(new PE());
....

[1]  

【责编:Peng】

--------------------next---------------------

阅读(472) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~