现在的位置: 首页 > 综合 > 正文

visitor—-设计模式

2013年07月13日 ⁄ 综合 ⁄ 共 3884字 ⁄ 字号 评论关闭

1.把数据结构与相关的处理分离开,另外写一个表示在数据结构内穿梭来去的主体“访客”的类,然后把处理交给这个类来进行。如此一来,如果想追加新的处理行为时,只要再建立一个新的“访客”即可。而在数据结构这边,也只要能接受来敲门的“访客”就能完成动作。

2.示例:

package com.cn.amk;

import java.util.Iterator;
import java.util.Vector;


abstract class Visitor {
	public abstract void visit(File file);
	public abstract void visit(Directory directory);
}

class ListVisitor extends Visitor{
	private String currentDir = "";
	public void visit(File file) {
		System.out.println(currentDir + "/" + file);
	}
	public void visit(Directory directory) {
		System.out.println(currentDir + "/" + directory);
		String saveDir = currentDir;
		currentDir = currentDir + "/" + directory.getName();
		Iterator<Entry> it = directory.iterator();
		while (it.hasNext()) {
			Entry entry = (Entry)it.next();
			System.out.println(this.currentDir + "   hehe");
			entry.accept(this);
		}
		currentDir = saveDir;
	}
}

interface Acceptor {
	public void accept(Visitor v);
}

abstract class Entry implements Acceptor{
	public abstract String getName();
	public abstract int getSize();
	public Entry add(Entry entry) throws FileTreatmentException {
		throw new FileTreatmentException();
	}
	public Iterator<Entry> iterator() throws FileTreatmentException {
		throw new FileTreatmentException();
	}
	public String toString() {
		return getName() + "<" + getSize() + ">";
	}
}

class File extends Entry {
	String name;
	int size;
	public File(String name, int size) {
		this.name = name;
		this.size = size;
	}
	public String getName() {
		return name;
	}
	public int getSize() {
		return size;
	}
	public void accept(Visitor v){
		v.visit(this);
	};
}

class Directory extends Entry {
	private String name;
	private Vector<Entry> directory = new Vector<Entry>();
	public Directory(String name) {
		this.name = name;
	}
	public String getName() {
		return name;
	}
	public int getSize() {
		int size = 0;
		Iterator<Entry> it = directory.iterator();
		while(it.hasNext()) {
			Entry entry = (Entry)it.next();
			size += entry.getSize();
		}
		return size;
	}
	public Iterator<Entry> iterator() {
		return directory.iterator();
	}
	public Entry add(Entry entry) {
		directory.add(entry);
		return this;
	}
	public void accept(Visitor v){
		v.visit(this);
	}
}

class FileTreatmentException extends RuntimeException {
	private static final long serialVersionUID = 1L;
	public FileTreatmentException() {
		
	}
	public FileTreatmentException(String msg) {
		super(msg);
	}
	
}

public class Main {
	public static void main(String[] args) {
		System.out.println("Making root entries...");
		Directory rootdir = new Directory("root");
		Directory bindir = new Directory("bin");
		Directory tmpdir = new Directory("tmp");
		Directory usrdir = new Directory("usr");
		
		rootdir.add(bindir);
		rootdir.add(tmpdir);
		rootdir.add(usrdir);
		bindir.add(new File("vi",10000));
		bindir.add(new File("latex",20000));
		rootdir.accept(new ListVisitor());
	}
}

这一示例的数据结构是文件层次结构。visitor提供对其层次的一个遍历行为。

3.另外一个例子:

package com.cn.dai;

import java.util.ArrayList;
import java.util.Iterator;

public class Test {
	public static void main(String[] args) {
		A a1 = new A(1);
		A a2 = new A(2);
		A a3 = new A(3);
		A a4 = new A(4);
		A a5 = new A(5);
		A a6 = new A(6);
		A a7 = new A(7);
		a5.setArrayList(a6);
		a5.setArrayList(a7);
		a1.setArrayList(a2);
		a1.setArrayList(a3);
		a3.setArrayList(a4);
		a3.setArrayList(a5);
		a1.accept(new ListVisit());
		
	}
}
abstract class Visitor {
	public abstract void visit(Entry entry);
}

class ListVisit extends Visitor{
	private int total;
	@Override
	public void visit(Entry entry) {
		
		total += entry.getN();
		System.out.println(entry.getN());
		System.out.println("total: " + total);
		Iterator<Entry> it = entry.iterator();
		while(it.hasNext()) {
			Entry en = (Entry)it.next();
			en.accept(this);
		}
		System.out.println("endtotal: " + total);
	}
	
}

interface Acceptor {
	public abstract void accept(Visitor v);
}
abstract class Entry implements Acceptor {
	public abstract void accept(Visitor v);
	public abstract int getN();
	public abstract void setArrayList(Entry n);
	public abstract Iterator<Entry> iterator();
}
class A extends Entry{
	private int n;
	private ArrayList<Entry> al = new ArrayList<Entry>();
	public A(int n) {
		this.n = n;
	}
	public A(int n,A a) {
		this.n = n;
		this.al.add(a);
	}
	public int getN() {
		return n;
	}
	public void setArrayList(Entry n) {
		al.add(n);
	}
	public void accept(Visitor v) {
		v.visit(this);
	}
	@Override
	public Iterator<Entry> iterator() {
		return al.iterator();
	}
}

这一例子的数据结构是一个用ArrayList构建的树,每个节点有其值。visitor的操作时遍历整个数,求整个数的数值和。

4.为什么要搞得这么复杂:

            visitor pattern的目的是要把处理从数据结构分出来。在集合元素或元素间的连结时,数据结构的地位非常重要。但是维持这个结构跟写一个以这个机构为基础的处理完全是两回事。

抱歉!评论已关闭.