码迷,mamicode.com
首页 > 其他好文 > 详细

访问者模式的意图

时间:2014-09-30 18:24:39      阅读:217      评论:0      收藏:0      [点我收藏+]

标签:设计模式   java   

Person有子类Boy、Girl;有方法say()、eat(int i)、walk()。据说eat与身高、心情等相关,有非常复杂的算法...,据说say()与walk()的代码放在一起,会显得不专业……

Person的这些代码,由子类实现。Person非常容易扩展出新的子类

package method.visitor;
public abstract class Person{
    public abstract void accept(Visitor v);
    /*
    public abstract String say();
    public abstract int eat(int i);//长肉
    public abstract void walk();
    */
}

但是,由于Person的这些方法的代码将分散到Boy、Gril中“导致整个系统难以理解”,更重要的是,Person增添新的方法困难——违反OCP、整个类层次需要修改。于是,有了访问者模式。从结构出发,访问者模式2中好人打贱人说明了一个事实,只要涉及双分派,就可以使用访问者模式。但是GoF的出发点:将Person的层次横切为Visitor层次

访问者是做专项检查的。

Person有n个子类m个方法,转换为Visitor则有m个子类n个方法,不管怎样n*m=m*n。访问者模式的最好使用场合:m越大n越小越好。换言之:访问者类型很多而对象结构中元素类型很少,这才适合访问者模式


重构后,Person的方法say()、eat(int i)、walk()变成了访问子类,只剩下accept。Visitor将对Person的子类进行访问。

package method.visitor;
/**
 * @author yqj2065
 * @version 2014.9
 */
public abstract class Visitor{
    public abstract void visit(Person p);    
    abstract void visitBoy();
    abstract void visitGirl();
}

package method.visitor;
import static tool.Print.*;
public class SayVisitor extends Visitor{
    public void visit(Person p){
        p.accept(this);
    } 
    @Override void visitBoy(){
        //Boy.say
        pln("Boy.say");
    }
    @Override  void visitGirl(){
        pln("Girl.say");
    }
}//EatVisitor、WalkVisitor略
所以,(Visitor或)EatVisitor表示“一个作用于某对象结构中的各元素的操作”,EatVisitor表示Person的eat(int i);

所以,Visitor“使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作”。如希望为Person增添song()操作,添加一个SongVisitor即可。

Person现在增添操作容易增添子类困难;以前则正好相反。


yqj2065个人不喜欢GoF的这一出发点,而且访问者对待Person的方法如eat(int i)涉及参数和返回值时比较麻烦。

绝大多数情况下,访问者使用的是 void visitBoy(Boy)访问者模式2中和这里的 void visitBoy(),是简单得有些不像话。


访问者模式的意图

标签:设计模式   java   

原文地址:http://blog.csdn.net/yqj2065/article/details/39697081

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!