1. 类图
- Visitor:访问者接口,为所有访问者声明一个方法,用来代表对对象结构添加的功能
- ConcreteVisitor:具体访问者,实现添加的功能
- Element:元素对象,对象结构的顶层接口,定义接收访问的操作
- ConcreteElement:具体元素对象,回调访问者的真实功能,开放自身的数据供访问者使用
- ObjectStructure:对象结构,包含多个被访问的对象
2. 示例
为可能扩展的对象预留回路,通过回调的方式进行功能扩展,避免对对象的修改
2.1 现有对象抽象类
public abstract class Customer {
private String id;
private String name;
// 接受访问者访问
public abstract void accetp(Visitor visitor);
}
2.2 现有对象实现
public class PersonCustomer extends Customer {
private String name;
private int age;
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public int getAge() {return age;}
public void setAge(int age) {this.age = age;}
@Override
public void accetp(Visitor visitor) {
// 回调访问者对象对应方法
visitor.visitPerson(this);
}
}
public class EnterpriseCustomer extends Customer {
private String linkman;
private String linkPhone;
private String regAddr;
public String getLinkman() {return linkman;}
public void setLinkman(String linkman) {this.linkman = linkman;}
public String getLinkPhone() {return linkPhone;}
public void setLinkPhone(String linkPhone) {this.linkPhone = linkPhone;}
public String getRegAddr() {return regAddr;}
public void setRegAddr(String regAddr) {this.regAddr = regAddr;}
@Override
public void accetp(Visitor visitor) {
// 回调访问者对象对应方法
visitor.vistiEnterprise(this);
}
}
2.3 访问者接口
为目标对象添加扩展功能
public interface Visitor {
// 访问个人用户
void visitPerson(PersonCustomer personCustomer);
// 访问企业用户
void vistiEnterprise(EnterpriseCustomer enterpriseCustomer);
}
2.4 具体访问者
为目标对象添加功能实现
public class ServiceRequestVisitor implements Visitor {
@Override
public void visitPerson(PersonCustomer personCustomer) {
System.out.println("个人用户:" + personCustomer.getName() + "请求服务");
}
@Override
public void vistiEnterprise(EnterpriseCustomer enterpriseCustomer) {
System.out.println("企业用户:" + enterpriseCustomer.getLinkman() + "请求服务");
}
}
2.5 对象结构
保存需要扩展的对象,触发扩展的方法
public class ObjectStructure {
private List<Customer> customerList = new ArrayList<>();
// 触发扩展功能
public void handle(Visitor visitor){
for (Customer customer : customerList) {
customer.accetp(visitor);
}
}
public void addElement(Customer customer){this.customerList.add(customer);}
}
2.6 客户端
public class Client {
public static void main(String[] args) {
// 用户创建
PersonCustomer personCustomer = new PersonCustomer();
personCustomer.setName("hiloj");
personCustomer.setAge(18);
EnterpriseCustomer enterpriseCustomer = new EnterpriseCustomer();
enterpriseCustomer.setLinkman("hiloj");
enterpriseCustomer.setLinkPhone("88888888");
enterpriseCustomer.setRegAddr("东方明珠第8层");
// 创建对象结构
ObjectStructure os = new ObjectStructure();
os.addElement(personCustomer);
os.addElement(enterpriseCustomer);
// 客户提出请求服务
ServiceRequestVisitor serviceRequestVisitor = new ServiceRequestVisitor();
os.handle(serviceRequestVisitor);
}
}
3. 优点
- 好的扩展性和复用性
- 分离无关的变化
4. 缺点
- 对象结构变化困难
- 破坏封装