• 通常访问者模式会结合组合模式一起来用。组合模式对我们的建议是:使用递归而非迭代去操作复杂的数据结构。访问者模式侧重将具体的操作逻辑与复杂数据结构分离出来。把操作逻辑放到访问者里面去。
    • 重构一下部门树,将之前的remove()等逻辑抽象为操作访问者的逻辑。
    1. public static class Department {
    2. private String name;
    3. private List<Department> children = new ArrayList<Department>();
    4. public Department(String name) {
    5. super();
    6. this.name = name;
    7. }
    8. public String getName() {
    9. return name;
    10. }
    11. public void setName(String name) {
    12. this.name = name;
    13. }
    14. public List<Department> getChildren() {
    15. return children;
    16. }
    17. public void setChildren(List<Department> children) {
    18. this.children = children;
    19. }
    20. //这里接客,可以观光
    21. public void accept(Visitor visitor) {
    22. visitor.visit(this);
    23. }
    24. }
    • 构造访问者接口,它专门处理对Department这种复杂数据结构的操作。
    1. public interface Visitor {
    2. void visit(Department dept);
    3. }
    • 实现访问者接口,构造删除部门和更新部门两种访问操作。
    1. public static class RemoveVisitor implements Visitor {
    2. public void visit(Department dept) {
    3. if(dept.getChildren().size() > 0) {
    4. for(Department child : dept.getChildren()) {
    5. //在这里实现递归遍历
    6. child.accept(this);
    7. }
    8. }
    9. System.out.println("删除部门【" + dept.getName() + "】");
    10. }
    11. }
    12. public static class UpdateStatusVisitor implements Visitor {
    13. private String status;
    14. public void visit(Department dept) {
    15. if(dept.getChildren().size() > 0) {
    16. for(Department child : dept.getChildren()) {
    17. //在这里实现递归遍历
    18. child.accept(this);
    19. }
    20. }
    21. System.out.println("将部门【" + dept.getName() + "】的状态修改为:" + status);
    22. }
    23. public UpdateStatusVisitor(String status) {
    24. this.status = status;
    25. }
    26. }
    • 测试
    1. public static void main(String[] args) {
    2. Department leafDept1 = new Department("叶子部门1");
    3. Department leafDept2 = new Department("叶子部门2");
    4. Department leafDept3 = new Department("叶子部门3");
    5. Department subDept1 = new Department("子部门1");
    6. subDept1.getChildren().add(leafDept1);
    7. subDept1.getChildren().add(leafDept2);
    8. Department subDept2 = new Department("子部门2");
    9. subDept2.getChildren().add(leafDept3);
    10. Department parentDept = new Department("父部门");
    11. parentDept.getChildren().add(subDept1);
    12. parentDept.getChildren().add(subDept2);
    13. Visitor removeVisitor = new RemoveVisitor();
    14. parentDept.accept(removeVisitor);
    15. Visitor updateStatusVisitor = new UpdateStatusVisitor("禁用");
    16. parentDept.accept(updateStatusVisitor);
    17. }