前言
- 访问者模式,是一种将数据操作和数据结构分离的设计模式.
- 大多数情况下,你并不需要使用访问者模式,但是当你一旦需要使用它时,那你就是真地需要它了.
定义
- 定义:封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作.
- 优点:
1.各角色职责分离,符合单一职责的原则
2.具有优秀的扩展性
3.使得数据结构和作用于结构上的操作解耦,使得操作集合可以独立变化
4.灵活性 - 缺点:
1.具体元素对访问者公布细节,违反了迪米特原则
2.具体元素变更时导致修改成本变大
3.违反了依赖导致原则,为了达到”区别对待”而依赖了具体类,没有依赖抽象. - 使用场景:
1.对象结构比较稳定,但经常需要在此对象结构上定义新的操作.
2.需要对一个对象结构中的对象进行很多不同的并且不相关的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作
UML类图
- Visitor:接口或者抽象类,它定义了对每一个元素的访问行为,它的参数就是可以访问的元素
- ConcreteVisitor:具体访问者,对每一个元素类访问的具体行为
- Element:元素接口或者抽象类,定义了一个accept方法,每一个月uansu都要可以被访问者访问
- ElementA:具体元素类,它提供了接受访问的具体方法实现
- ObjectStructure:对象结构,内部管理元素集合,并且可以迭代这些元素供访问者访问
实现步骤
- 案例:CTO和CEO分别对员工manager和Engineer评定绩效.但两个visitor所考核的属性不一样.
- visitor:
/**
* 访问接口
* 分别对这两个职位进行访问
* @author max
* */
public interface Visitor {
public void visit(Engineer engineer);
public void visit(Manager manager);
}
- CEOVisitor和CTOVisitor:具体访问者,获取对应想要visit对象的属性.
/**
* 具体访问者CEO
* @author Administrator
*
*/
public class CEOVisitor implements Visitor {
@Override
public void visit(Engineer engineer) {
}
@Override
public void visit(Manager manager) {
}
}
- Stuff:基类说明有什么属性,不过最重要的,是有accept()方法用来接收访问者,
/**
* 员工基类
* @author max
* */
public abstract class Stuff {
public String name;
public int kpi;
public Stuff(String name) {
super();
this.name = name;
this.kpi = new Random().nextInt(10);
}
public abstract void accept(Visitor visitor);
}
- Engineer和Manager是具体实现类:两个岗位都有不同的绩效考核标准
/**
* 工程师
* @author max
*
*/
public class Engineer extends Stuff {
public Engineer(String name) {
super(name);
kpi = getCodeLines();
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
public int getCodeLines(){
return new Random().nextInt(10);
}
}
BussinessReport report = new BussinessReport();
report.showReport(new CEOVisitor());
report.showReport(new CTOVisitor());
源码下载