访问者模式

411 阅读2分钟

概念

用于封装一些作用于某种稳定的对象结构(不会经常添加删除元素)中各对象元素的操作,而且又不改变这个对象结构。比如有一个对象结构有很多对象组成,每个对象都拥有一个accept方法用来接受访问者对象的访问。访问者是一个接口,拥有一个visit方法。在对对象结构遍历时对每个元素都实施accept方法,该方法又会调用访问中的visit方法(用于处理不同的对象元素)

优点

扩展性好,使得数据结构和操作结构解耦

缺点

违背了依赖倒置原则,具体元素改变时修改成本大。

实现方式

  • Visitor —— 访问者接口或抽象类,定义对每个元素的访问行为,理论上其方法数与元素个数一样(每个元素对应有一个visit(ElementX e))(即通过方法的重载处理不同的元素)
  • ConcreteVisitor —— 具体访问者
  • Element —— 元素接口或抽象类,定义了accept方法
  • ElementA ,ElementB—— 具体元素类
  • ObjectStructure —— 对象结构。内部管理元素集合,并可以迭代给Visitor访问。
/* 元素类*/
public abstract class Staff {
    public String name;
    public int kpi;
    public abstract void accept(Visitor visitor);
}

public class Engineer extends Staff {
    @Override
    public void accept (Visitor visitor){
        visitor.visit(this);
    }

    public int getkpi(){
        return 1500;
    }
}
public class Manager extends Staff {

    @Override
    public void accept (Visitor visitor){
        visitor.visit(this);
    }

    public int getproductandkpi(){
        return 1000
    }
}

/*对象结构*/
public class BusinessReport{
    List<Staff> l = new LinkedList();

    public BusinessReport(){

    /*初始化列表
    l.add(new Manager("王经理"));
    ...
    */
    }

    public void showResult(Visitor visitor){
        for(Staff s : l){
            s.accept(visitor);
        }
    }
}

/* 访问者 */
public interface Visitor {
    public void visit(Engineer e);
    public void visit(Manager e);
}
//访问者1
public class CEOVisitor implements Visitor {
    @Override
    public void visit(Engineer e){
        System.out.println(e.kpi);    
    }
    @Override
    public void visit(Manager e){
        System.out.println(e.kpi + “ OK”);
    }
}
//访问者2 。。。可以定义不同访问者不同的操作