var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-20738293-1']); _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script')"/>
jutleo
欢迎走进有风的地方~~
posts - 63,  comments - 279,  trackbacks - 0
    dom4j遍历xml文档树有种很特别的方式就是访问者(Visitor)模式,初次接触Visitor模式,写出个人理解大家交流!
Visitor
访问者模式定义:作用于某个对象树中各个对象的操作. 它可以使你在不改变这些对象树本身的情况下,定义作用于这些对象树各个节点的新操作。


先看以下代码:Person为简单的vo
package org.bulktree.visitor;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
 * 
 * 
@author bulktree Email: laoshulin@gmail.com
 * @date Aug 10, 2008
 
*/

public class ReadCollection {

    
private Collection c = null;

    ReadCollection() 
{

        
/*
         * 准备数据-String对象-Person对象-Integer对象-List对象
         
*/

        String str 
= "bulktree.laoshulin";
        Person person 
= new Person("bulktree""22""M");
        Integer a 
= new Integer(99);
        
/*
         * 使用范型
         
*/

        List
<String> list = new ArrayList<String>();
        list.add(
"BULKTREE");
        list.add(
"LAOSHULIN");
        list.add(
"OAKERTREE");

        c 
= new ArrayList();
        c.add(str);
        c.add(person);
        c.add(a);
        c.add(list);

    }


    
/**
     * 遍历Collection中的每一个对象并打印
     
*/

    
public void testCollection() {
        Iterator iter 
= getCollection().iterator();

        
while (iter.hasNext()) {
            Object o 
= iter.next();

            
if (o instanceof String) {
                System.out.println(
"String-->  " + o.toString());
            }
 else if (o instanceof Person) {
                readPerson((Person) o);
            }
 else if (o instanceof Integer) {
                Integer inta 
= (Integer) o;
                System.out.println(inta.intValue());
            }
 else if (o instanceof List) {
                readList((List) o);
            }

        }


    }


    
public Collection getCollection() {
        
return c;
    }


    
private void readPerson(Person person) {
        System.out.println(
"person-name-> " + person.getName());
        System.out.println(
"person-age-> " + person.getAge());
        System.out.println(
"person-sex-> " + person.getSex());
    }


    
private void readList(List<String> list) {
        
/*
         * 增强的for循环
         
*/

        
for (String s : list) {
            System.out.println(s);
        }

    }


    
public static void main(String[] args) {
        
new ReadCollection().testCollection();
    }

}


    我们使用了
instanceof来判断 Object对象 o 的类型,这样做的缺点是代码中If/else if 很繁琐,而JDK中的范型又限制了只能使用相同的类型,这时Vistor访问模式派上用场了。

当我们要访问Collection的每一个Element(被访问者)时,定义一个accept操作使其具有可被访问性,我们定义一个Visiable接口,使Collection的每一个Element继承这个接口,实现自身的访问操作
package org.bulktree.visitor;

/**
 * 可访问性--接收一个访问者
 * 
@author bulktree Email: laoshulin@gmail.com
 * @date Aug 10, 2008
 
*/

public interface Visitable {
    
public void accept(Visitor visitor);
}
 

下来是四个被访问的类型String,Integer,Person,Collection的实现类

package org.bulktree.visitor;

/**
 * 被访问者--String对象
 * 
@author bulktree Email: laoshulin@gmail.com
 * @date Aug 10, 2008
 
*/

public class StringElement implements Visitable {

    
private String str;

    
public StringElement(String str) {
        
this.str = str;
    }


    
public String getStr() {
        
return str;
    }


    
public void accept(Visitor visitor) {
        visitor.visitString(
this);
    }

}

package org.bulktree.visitor;

/**
 * 被访问者--Integer对象
 * 
@author bulktree Email: laoshulin@gmail.com
 * @date Aug 10, 2008
 
*/

public class IntegerElement implements Visitable {

    
private Integer i;
    
    
public IntegerElement(Integer i) {
        
this.i = i;
    }

    
    
public Integer getI() {
        
return i;
    }

    
    
public void accept(Visitor visitor) {
        visitor.visitInteger(
this);

    }

}

package org.bulktree.visitor;

import java.util.Collection;

/**
 * 被访问者--Person对象
 * 
@author bulktree Email: laoshulin@gmail.com
 * @date Aug 10, 2008
 
*/

public class PersonElement implements Visitable{
    
private Person p;
    
    
public PersonElement(Person p) {
        
this.p = p;
    }

    
    
public Person getP() {
        
return p;
    }


    
public void accept(Visitor visitor) {
        visitor.visitPerson(
this);
    }

}

package org.bulktree.visitor;

import java.util.Collection;
import java.util.List;

/**
 * 被访问者--Collection对象
 * 
@author bulktree Email: laoshulin@gmail.com
 * @date Aug 10, 2008
 
*/

public class CollectionElement implements Visitable {

    
private Collection collection;

    
public CollectionElement(Collection collection) {
        
this.collection = collection;
    }


    
public Collection getCollection() {
        
return collection;
    }


    
public void accept(Visitor visitor) {
        visitor.visitCollection(collection);
    }

}


下来定义一个访问者
Visitor接口,它可以访问Integer,String,Person(VO对象),Collection类型

package org.bulktree.visitor;

import java.util.Collection;

/**
 * 访问者接口
 * 
@author bulktree Email: laoshulin@gmail.com
 * @date Aug 10, 2008
 
*/

public interface Visitor {
    
public void visitString(StringElement str);
    
public void visitInteger(IntegerElement i);
    
public void visitCollection(Collection collection);
    
public void visitPerson(PersonElement perE);
}
关键的Visitor实现类

package org.bulktree.visitor;

import java.util.Collection;
import java.util.Iterator;

/**
 * 访问者实现类
 * 
@author bulktree Email: laoshulin@gmail.com
 * @date Aug 10, 2008
 
*/

public class VisitorImpl implements Visitor {

    
/*
     *访问字符串,仅对字符串输出 
     
*/

    
public void visitString(StringElement str) {
        System.out.println(
"*******************字符串输出*************************");
        System.out.println(str.getStr());
    }


    
/**
     * 访问Integer类型
     
*/

    
public void visitInteger(IntegerElement i) {
        System.out.println(
"*******************整型输出*************************");
        System.out.println(i.getI());
    }


    
/**
     * 访问Collection对象,遍历每一个元素
     * 使用了一个if语句判断属于Visitable哪一个被访问对象,然后调用相应的accept方法
     * 实现递归调用
     
*/

    
public void visitCollection(Collection collection) {
        Iterator iter 
= collection.iterator();
        
while (iter.hasNext()) {
            Object o 
= iter.next();
            
if (o instanceof Visitable) {
                ((Visitable) o).accept(
this);
            }

        }

    }


    
/**
     * 访问单个Person对象
     
*/

    
public void visitPerson(PersonElement perE) {
        System.out.println(
"*******************Person对象输出*************************");
        Person person 
= perE.getP();
        System.out.println(
"person-name-> " + person.getName());
        System.out.println(
"person-age-> " + person.getAge());
        System.out.println(
"person-sex-> " + person.getSex());
    }


}

    客户端测试:
package org.bulktree.visitor;

import java.util.ArrayList;
import java.util.Collection;

/**
 * Visitor模式客户端
 * 
@author bulktree Email: laoshulin@gmail.com
 * @date Aug 10, 2008
 
*/

public class VisitorMain {

    
public static void main(String[] args) {
        Visitor visitor 
= new VisitorImpl();

        
        
/*
         * 访问字符串
         
*/

        System.out.println(
"======================访问字符串=========================");
        StringElement stringE 
= new StringElement(
                
"bulktree.laoshulin.oakertree");
        visitor.visitString(stringE);

        
/*
         * 访问集合
         
*/

        System.out.println(
"=======================访问集合========================");
        Collection list 
= new ArrayList();

        StringElement str1 
= new StringElement("aaa");
        StringElement str2 
= new StringElement("bbb");
        list.add(str1);
        list.add(str2);
        
        PersonElement perE1 
= new PersonElement(new Person("LAOSHULIN""22""M"));
        PersonElement perE2 
= new PersonElement(new Person("BULKTREE""21""W"));
        list.add(perE1);
        list.add(perE2);
        
        IntegerElement intE1 
= new IntegerElement(new Integer(99));
        IntegerElement intE2 
= new IntegerElement(new Integer(100));
        list.add(intE1);
        list.add(intE2);
        
        visitor.visitCollection(list);

        
/*
         * 访问Person
         
*/

        System.out.println(
"======================访问Person=========================");
        Person p 
= new Person("BULKTREE""22""M");
        PersonElement perE 
= new PersonElement(p);
        visitor.visitPerson(perE);
        
        
/*
         * 访问Integer
         
*/

        System.out.println(
"=====================访问Integer==========================");
        IntegerElement intE 
= new IntegerElement(new Integer(77));
        visitor.visitInteger(intE);
    }

}

     使用访问者模式的前提是对象群结构中
(Collection) 中的对象类型很少改变,在两个接口Visitor(访问)Visitable(可访问)中,确保Visitable很少变化,也就是说,确保不能有新的元素类型加进来,可以变化的是访问者行为或操作,也就是Visitor的不同子类可以有多种,这样使用访问者模式最方便,当系统中存在着固定的数据结构,且有着不同的行为,访问者模式也许是个不错的选择
posted on 2008-08-10 12:12 凌晨风 阅读(2019) 评论(2)  编辑  收藏 所属分类: Java学习笔记

FeedBack:
# re: Visitor访问者模式---------学习dom4j时遇到的顺便拿来交流
2008-09-05 17:15 | Person在哪
Person在哪  回复  更多评论
  
# re: Visitor访问者模式---------学习dom4j时遇到的顺便拿来交流
2008-09-09 11:47 | 凌晨风
哥们简单的vo类啊!  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
 

<2008年8月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
31123456

常用链接

留言簿(11)

我参与的团队

随笔分类

随笔档案

文章分类

文章档案

新闻分类

新闻档案

收藏夹

围脖

最新随笔

搜索

  •  

最新评论

阅读排行榜

评论排行榜