GoF设计模式之二十三 Visitor- -

来源:百度文库 编辑:神马文学网 时间:2024/04/28 10:27:12
C11) Visitor(访问者模式)
定义:描述一个作用于对象结构中的元素的操作,访问者模式使得不改变所操作元素的类就可以定义一个新的操作。
这个模式,在客户端和被其操作的对象之间建立了一个访问者,客户端通过访问者访问被操作对象,一方面降低耦合,另一方面方便改变操作的动作。非常适合应用在有多种类型的被操作对象的场合,比如集合对象。
现在假设有一个存放备注集合的对象,其中可能的元素有字条MemoStr、日期MemoDate、金额MemoDbl,那通常会用的方法如下,定义3个对象
public class MemoStr {
private int memoId;
private String memo;
}
public class MemoDate {
private int memoId;
private Date memo;
}
public class MemoDbl {
private int memoId;
private double memo;
}
客户端访问
Collection memos = new ArrayList();
memos.add(new MemoStr(1,"明天休息"));
memos.add(new MemoDate(2,new Date()));
memos.add(new MemoDbl(3,1136.5));
Iterator itr = memos.Iterator();
while (itr.hasNext()) {
Object o = itr.next();
if (o instanceof MemoStr) {
System.out.println(((MemoStr)o).getMemo());
}else if (itr.next() instanceof MemoDate) {
SimpleDateFormat df = new SimpleDateFormat("YY/MM/DD");
System.out.println(df.format(((MemoDate)o).getMemo()));
}else if (itr.next() instanceof MemoDbl) {
DecimalFormat df = new DecimalFormat("#,#0.00");
System.out.println(df.format(((MemoDbl)o).getMemo()));
}
}
以上是通常的做法,来看看使用访问者模式带来的变化。
首先,定一个接口和一个访问者对象
public interface Visitable {
public void accept(Visitor visitor);
}
public class Visitor {
public void visitShow(MemoStr str) {
System.out.println(str.getMemo());
}
public void visitShow(MemoDate day) {
SimpleDateFormat df = new SimpleDateFormat("YY/MM/DD");
System.out.println(df.format(day.getMemo()));
}
public void visitShow(MemoDbl dbl) {
DecimalFormat df = new DecimalFormat("#,#0.00");
System.out.println(df.format(dbl.getMemo()));
}
}
MemoStr等3个对象必须实现Visitable接口,以MemoStr为例
public class MemoStr implements Visitable {
private int memoId;
private String memo;
public void accept(Visitor visitor) {
visitor.visitShow(this)
}
}
完成后,客户端的调用变为
Visitor visitor = new Visitor();
Iterator itr = memos.Iterator();
while (itr.hasNext()) {
Object o = itr.next();
if (o instanceof Visitable) {
((Visitable)o).accept(visitor);
}
}
将对象和操作分离,在需要修改操作部分时,仅改变Visitor就可以完成对所有客户端的修改,而当添加了新的元素如MemoTel等时,也只需在Visitor中添加访问方法。这样就完成了访问者模式,在不知道对象类型的情况下,用不着猜测对象的类型,直接让对象来告诉我们该如何操作它。由于是面向接口,可扩展性非常好。
参考:
1、http://www.jdon.com/designpatterns/visitor.htm(中文、java实例)
2、http://www.dofactory.com/Patterns/PatternVisitor.aspx(英文、C#实例、UML)
3、http://www.caterpillar.onlyfun.net/PmWiki/pmwiki.php/DesignPattern/VisitorPattern(中文、java实例、UML)推荐
4、http://www.techscore.com/tech/DesignPattern/Visitor.html(日文、java实例、UML)推荐