一、什么是访问者模式
Visitor模式也叫访问者模式,是行为模式之一 ,它分离对象的数据和行为,使用Visitor模式, 可以不修改已有类的情况下,增加新的操作。
二、访问者模式的应用示例
比如有一个公园,有一到多个不同的组成部分;该公 园存在多个访问者:清洁工A负责打扫公园的A部分,清 洁工B负责打扫公园的B部分,公园的管理者负责检点各 项事务是否完成,上级领导可以视察公园等等。也就是 说,对于同一个公园,不同的访问者有不同的行为操 作,而且访问者的种类也可能需要根据时间的推移而变 化(行为的扩展性)。
根据软件设计的开闭原则(对修改关闭,对扩展开 放),我们怎么样实现这种需求呢?
三、访问者模式的结构
四、访问者模式的角色和职责
1) 访问者角色(Visitor): 为该对象结构中具体元素角色声明一个访问操作接口。该操作接 口的名字和参数标识了发送访问请求给具体访问者的具体元素角色。 这样访问者就可以通过该元素角色的特定接口直接访问它。
2) 具体访问者角色(Concrete Visitor): 实现每个由访问者角色(Visitor)声明的操作。
3) 元素角色(Element): 定义一个Accept操作,它以一个访问者为参数。
4) 具体元素角色(Concrete Element): 实现由元素角色提供的Accept操作。
5) 对象结构角色(Object Structure): 这是使用访问者模式必备的角色。它要具备以下特征:能枚举 它的元素;可以提供一个高层的接口以允许该访问者访问它的元 素;可以是一个复合(组合模式)或是一个集合,如一个列表或一个无序 集合。
公园每一部分的抽象
1 // 公园每一部分的抽象 2 public interface ParkElement { 3 //用来接纳访问者 4 public void accept(Visitor visitor); 5 }
公园
1 //公园 2 public class Park implements ParkElement { 3 private String name; 4 private ParkA parkA; 5 private ParkB parkB; 6 7 public Park() { 8 this.parkA = new ParkA(); 9 this.parkB = new ParkB(); 10 parkA.setName("A"); 11 parkB.setName("B"); 12 } 13 14 public void accept(Visitor visitor) { 15 visitor.visit(this); 16 parkA.accept(visitor); 17 parkB.accept(visitor); 18 19 } 20 21 public String getName() { 22 return name; 23 } 24 25 public void setName(String name) { 26 this.name = name; 27 } 28 }
公园的A部分
1 // 公园的A部分 2 public class ParkA implements ParkElement { 3 private String name; 4 5 public String getName() { 6 return name; 7 } 8 9 public void setName(String name) { 10 this.name = name; 11 } 12 13 public void accept(Visitor visitor) { 14 visitor.visit(this); 15 } 16 }
公园的B部分
1 // 公园的B部分 2 public class ParkB implements ParkElement{ 3 private String name; 4 5 public String getName() { 6 return name; 7 } 8 9 public void setName(String name) { 10 this.name = name; 11 } 12 13 public void accept(Visitor visitor) { 14 visitor.visit(this); 15 } 16 }
访问者
1 // 访问者 2 public interface Visitor { 3 public void visit(Park park); 4 public void visit(ParkA parkA); 5 public void visit(ParkB parkB); 6 }
清洁工A,负责parkA的卫生情况
1 // 清洁工A,负责parkA的卫生情况 2 public class VisitorA implements Visitor { 3 4 public void visit(Park park) { 5 6 } 7 8 public void visit(ParkA parkA) { 9 System.out.println("清洁工A:完成公园" + parkA.getName()+ "的卫生"); 10 } 11 12 public void visit(ParkB parkB) { 13 14 } 15 }
清洁工B,负责公园B部分的卫生
1 // 清洁工B,负责公园B部分的卫生 2 public class VisitorB implements Visitor { 3 4 public void visit(Park park) { 5 6 } 7 8 public void visit(ParkA parkA) { 9 10 } 11 12 public void visit(ParkB parkB) { 13 System.out.println("清洁工B:完成公园" + parkB.getName()+"的卫生"); 14 } 15 }
管理员
1 //管理员 2 public class VisitorManager implements Visitor { 3 4 public void visit(Park park) { 5 System.out.println("管理员:负责" + park.getName() + "卫生检查"); 6 } 7 8 public void visit(ParkA parkA) { 9 System.out.println("管理员:负责公园"+ parkA.getName() +"部分卫生检查"); 10 } 11 12 public void visit(ParkB parkB) { 13 System.out.println("管理员:负责公园"+ parkB.getName() +"分部卫生检查"); 14 } 15 }
测试
1 public class MainClass { 2 public static void main(String[] args) { 3 Park park = new Park(); 4 park.setName("越秀公园"); 5 VisitorA visitorA = new VisitorA(); 6 7 park.accept(visitorA); 8 9 VisitorB visitorB = new VisitorB(); 10 park.accept(visitorB); 11 12 VisitorManager visitorManager = new VisitorManager(); 13 park.accept(visitorManager); 14 } 15 }