首页 > 代码库 > 设计模式_訪问者模式

设计模式_訪问者模式

Visitor Pattern 

   Repressent an operation to be performed  on the elements of an object structure.Visitor lets you define a new operation without changing the classees of the elements on which it operates.(封装一些作用于某种数据结构中的各种元素的操作,它能够在不改变数据结构的前提下定义作用于这些元素的新操作。)


直接上代码吧,心态不佳。

 

public abstract class Employee {
 public final static int MALE=0;
 public final static int FEMALE=1;
 
 private String name;
 private String salary;
 private int sex;
 
 public abstract void accept(IVisitor visitor); //allow a visitor
 
 
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public String getSalary() {
  return salary;
 }
 public void setSalary(String salary) {
  this.salary = salary;
 }
 public int getSex() {
  return sex;
 }
 public void setSex(int sex) {
  this.sex = sex;
 }
}

public class Manager extends Employee{
 private String performance;
 
 public String getPerformance() {
  return performance;
 }
 public void setPerformance(String performance) {
  this.performance = performance;
 }
 @Override
 public void accept(IVisitor visitor) {
  visitor.visit(this);
 }
}

public class CommonEmployee extends Employee{
 private String job;
 
 public String getJob() {
  return job;
 }
 public void setJob(String job) {
  this.job = job;
 }
 @Override
 public void accept(IVisitor visitor) {
  visitor.visit(this);
 }
}

public interface IVisitor {
 public void visit(CommonEmployee commonEmployee);
 public void visit(Manager manager);
}
真正的处理类在这里。

public class Visitor implements IVisitor {
 public void visit(CommonEmployee commonEmployee) {
  System.out.println(this.getCommonEmployee(commonEmployee));
 }
 public void visit(Manager manager) {
  System.out.println(this.getManagerInfo(manager));
 }
 private String getBasicInfo(Employee employee) {
  String info = "name:" + employee.getName() + "\t sex:"
    + (employee.getSex() == Employee.FEMALE ?

"man" : "women") + "\t salary:" + employee.getSalary(); return info; } private String getManagerInfo(Manager manager) { String basic = this.getBasicInfo(manager); String otherInfo = "\t performance" + manager.getPerformance(); return basic + otherInfo; } private String getCommonEmployee(CommonEmployee commonEmployee){ String basic=this.getBasicInfo(commonEmployee)+"\t"; String other="job:"+commonEmployee.getJob(); return basic+other; } }


測试

public class Client {
 public static void main(String[] args) {
  for(Employee e:mockEmployee()){
   e.accept(new Visitor());
  }
 }
 
 public static List<Employee> mockEmployee(){
  List<Employee> list=new ArrayList<Employee>();
 
  CommonEmployee zhangsan=new CommonEmployee();
  zhangsan.setJob("coding everyday!");
  zhangsan.setName("zhangsan");
  zhangsan.setSalary("1800");
  zhangsan.setSex(Employee.MALE);
 
  CommonEmployee lirong=new CommonEmployee();
  lirong.setJob("page coding,It‘s not fansion");
  lirong.setName("lirong");
  lirong.setSalary("1900");
  lirong.setSex(Employee.FEMALE);
 
  Manager wang=new Manager();
  wang.setName("wamg");
  wang.setPerformance("It‘s unpay basically,but he is a horser!");
  wang.setSalary("10221");
  wang.setSex(Employee.MALE);
 
  list.add(zhangsan);
  list.add(lirong);
  list.add(wang);
  return list;
 }
}

长处 
● 符合单一职责原则
● 优秀的扩展性
● 灵活性很高

缺点
● 详细元素对訪问者发布细节
● 详细元素变更比較困难
● 违背了依赖倒置转原则

使用场景
 ● 一个对象结构包括非常多类对象,它们有不同的接口,而你想对这些对象实施一些依赖 于其详细类的操作。也就说是用迭代器模式已经不能胜任的情景。 

● 须要对一个对象结构中的对象进行非常多不同而且不相关的操作,而你想避免让这些操 作“污染”这些对象的类。



扩展实例
 
1.统计功能
 统计工资total仅仅须要在IVisitor抽象中加入一个public int getTotalSalary();然后在详细訪问者中实现就可以。

 


public class Visitor implements IVisitor {
//部门经理的工资系数是5
private final static int MANAGER_COEFFICIENT = 5;
//员工的工资系数是2
private final static int COMMONEMPLOYEE_COEFFICIENT = 2;
//普通员工的工资总和
private int commonTotalSalary = 0;
//部门经理的工资总和
private int managerTotalSalary =0;
//计算部门经理的工资总和
private void calManagerSalary(int salary){
this.managerTotalSalary = this.managerTotalSalary + salary
*MANAGER_COEFFICIENT ;
}
//计算普通员工的工资总和
private void calCommonSlary(int salary){
this.commonTotalSalary = this.commonTotalSalary +
salary*COMMONEMPLOYEE_COEFFICIENT;
}
//获得全部员工的工资总和
public int getTotalSalary(){
return this.commonTotalSalary + this.managerTotalSalary;
}
}

2.多个訪问者
由展示->汇总
IShowVisitor extends IVisitor 
ITotalVisitor  extends IVisitor

双分派
java的静态绑定和动态绑定。多态,重写,重载。 

你调用我的,我调用你的。谁是主谁是次,真正在哪里处理问题。 


我是菜鸟,我在路上。

设计模式_訪问者模式