設計模式_訪問者模式

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的靜態綁定和動態綁定,多態,重寫,重載。 

你調用我的,我調用你的。誰是主誰是次,真正在哪裏處理問題。 


我是菜鳥,我在路上。

發佈了78 篇原創文章 · 獲贊 17 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章