Fork me on GitHub

从不同角度看同一数据结构-访问者模式

访问者模式是一种复杂的设计模式,使用频率不高,下面举一个公司对员工业绩考核的例子,CEO和CTO对员工的考核标准是不一样的

员工抽象类

1
2
3
4
5
6
7
8
9
10
public abstract class Staff {
public String name;
public int kpi;
public Staff(String name) {
this.name = name;
kpi = new Random().nextInt(10);
}

public abstract void accept(Visitor visitor);
}

基类中只有员工的公共属性,这里是姓名和kpi

员工具体类

  1. 工程师类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class Engineer extends Staff {
    public Engineer(String name) {
    super(name);
    }

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

    public int getCodeLines() {
    return new Random().nextInt(10*10000);
    }
    }
  2. 产品经理类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Manager extends Staff {
public Manager(String name) {
super(name);
}

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

public int getProducts() {
return new Random().nextInt(10);
}
}

在具体类中加入独特的属性,这样访问者访问时就可以区别对待

抽象访问者类

1
2
3
4
public interface Visitor {
void visit(Engineer engineer);
void visit(Manager manager);
}

具体访问类

  1. CEO:只关心员工的姓名和KPI

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class CEO implements Visitor {
    @Override
    public void visit(Engineer engineer) {
    System.out.println("Engineer:"+ engineer.name + ", kpi: " +engineer.kpi);
    }

    @Override
    public void visit(Manager manager) {
    System.out.println("Manager: "+ manager.name + ", kpi: "+manager.kpi);
    }
    }
  2. CTO:根据岗位的不同关心不同的技术指标

1
2
3
4
5
6
7
8
9
10
11
public class CTO implements Visitor {
@Override
public void visit(Engineer engineer) {
System.out.println("Engineer: " + engineer.name +", code: " + engineer.getCodeLines());
}

@Override
public void visit(Manager manager) {
System.out.println("Manager: " + manager.name + ", product: "+ manager.getProducts());
}
}

具体示例如下

1
2
3
4
5
6
7
8
9
public class Main {
public static void main(String[] args) {
BusinessReport businessReport = new BusinessReport();
System.out.println("======CEO=====");
businessReport.showReport(new CEO());
System.out.println("\n=====CTO=====");
businessReport.showReport(new CTO());
}
}

结果

捕获.PNG

访问者模式可以很方便地添加访问者,方便地从多种角度观察同一种数据结构