风动破

导航

设计模式之Visitor访问者

http://www.cnblogs.com/saville/archive/2012/07/10/2584396.html 

一、概述
由于需求的改变,某些类常常需要增加新的功能,但由于种种原因这些类层次必须保持稳定,不允许开发人员随意修改。对此,访问者模式可以在不更改类层次结构的前提下透明的为各个类动态添加新的功能。
二、访问者模式
访问者模式表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。其结构图如下:

Visitor为每一个ConcreteElement声明一个Visitor操作。
ConcreteVisitor实现了Visitor声明的操作,其定义的行为就是需要动态添加到ConcreteElement中的新功能。
Element定义一个以Visitor为参数的Accept操作。
ConcreteElement实现Accept操作。
ObjectStructure能枚举它的元素,可以提供一个高层接口以允许访问者访问它的元素。
访问者模式通过双重分派(double dispatch)的方法来透明的为各个类添加新的功能,第一重分派是指Accept方法的多态,第二重分派是指Visit方法的多态。
访问者模式的主要缺点在于增添新的Element子类的时候会导致Visitor类发生改变,而且随着Element子类的增加,Visitor类会越来越庞大。
三、示例
我们看一下访问者模式的简单应用。
首先定义一个公司的员工管理系统的基本员工类,这个类层次要求保持稳定,不得随意添加内容。对此就需要给这些类增加一个Accept方法用于将来的动态扩展。

================================ 

public class VisitorMode

    {
        public VisitorMode() {           
    Manager manager = new Manager("经理");
            manager.Accept(new Salary());
            Chairman chair = new Chairman("会长");
            chair.Accept(new Salary());
        }
    }
    public abstract class IEmployee {
        public string name;
        public IEmployee() { }
        public IEmployee(string name) {
            this.name = name;
        }
        public abstract void Accept(IVisitor visitor);
    }
    public interface IVisitor {
        void Visiter(Manager man);
        void Visiter(Chairman man); 
    }
    /// <summary>
    /// 经理
    /// </summary>
    public class Manager : IEmployee
    {
        public Manager(string name) {
            this.name = name;
        }
        public override void Accept(IVisitor visitor)
        {
            visitor.Visiter(this);
        }
    }
    /// <summary>
    /// 主席/会长
    /// </summary>
    public class Chairman : IEmployee
    {
        public Chairman(string name) {
            this.name = name;
        }
        public override void Accept(IVisitor visitor)
        {
            visitor.Visiter(this);
        }
    }
    public class Salary : IVisitor {
        public void Visiter(Manager man)
        {
            Console.WriteLine(man.name+"工资:10000");
        }
        public void Visiter(Chairman man)
        {
            Console.WriteLine(man.name + "经理工资:100000");
        }
    }

posted on 2015-05-04 16:21  风动破  阅读(155)  评论(0)    收藏  举报