定义:封装一些作用于某种数据结构中的个元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。
角色职责如下:
Visitor 抽象访问者-----抽象类或者接口 声明访问者可以访问哪些元素。
ConcreteVisitor---------具体访问者,它影响访问者访问到一个类后该做什么。
Element-----------抽象元素 接口或者抽象类,声明接受哪一类访问者访问,通过accept方法中的参数类定义。
ConcreteElement---------具体元素,实现accept方法,通常是visitor.visit(this),基本上都形成一种模式了。
ObjectStruture---------结构对象 元素产生者,一般容纳在多个不同类 不同接口的容器,如List Map等,在项目中 一般很少抽象出这个角色。
/**
* 抽象访问者
*
*/
public interface IVisitor {
/**
* 访问普通员工
* @param commonEmployee
*/
public void visit(CommonEmployee commonEmployee);
/**
* 访问管理层员工
* @param managerEmployee
*/
public void visit(ManagerEmployee managerEmployee);
}
/**
* 具体访问者
*
*/
public class Visitor implements IVisitor{
/**
* 访问到一个类后,该做啥
*/
@Override
public void visit(ManagerEmployee managerEmployee) {
getManagerInfo(managerEmployee);
}
@Override
public void visit(CommonEmployee commonEmployee) {
getBasicInfo(commonEmployee);
}
public void getManagerInfo(Employee employee){
System.out.println("领导的 业绩。。。。");
}
public void getBasicInfo(Employee employee){
System.out.println("普通员工。。。。。");
}
}
public abstract class Employee {
private String name ;
private int age ;
private int salary ;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
/**
* 声明接受哪一类访问者访问
* @param visitor
*/
public abstract void accept(IVisitor visitor);
}
public class CommonEmployee extends Employee {
@Override
public void accept(IVisitor visitor) {
visitor.visit(this);
}
}
public class ManagerEmployee extends Employee {
@Override
public void accept(IVisitor visitor) {
visitor.visit(this);
}
}
/**
* 结构对象
*
*/
public class Client {
public static void main(String[] args){
ArrayList<Employee> employees = getEmployees();
for(Employee employee:employees){
employee.accept(new Visitor());
}
}
public static ArrayList<Employee> getEmployees(){
ArrayList<Employee> employees = new ArrayList<Employee>();
CommonEmployee zhangsan = new CommonEmployee();
zhangsan.setAge(23);
zhangsan.setName("zhangsan");
zhangsan.setSalary(10000);
ManagerEmployee lisi = new ManagerEmployee();
lisi.setAge(33);
lisi.setName("lisi");
lisi.setSalary(20000);
employees.add(zhangsan);
employees.add(lisi);
return employees;
}
}
访问者模式的优点:
1 符合单一职责原则 Employee抽象类的两个子类负责数据加载,Visitor负责报表的展现,不同的职责非常明确的分离开。
2.优秀的扩展性
3.灵活性高
缺点:
1.具体元素对访问者公布细节
2.具体元素变更比较困难
3.违背了依赖倒置原则 访问者依赖的是具体元素。