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

来源:百度文库 编辑:神马文学网 时间:2024/04/28 01:45:01

 

                                      

    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)推荐