1. 实现
//各种客户的父类
public abstract class Customer {
private String customerId;// 客户编号
private String name; //客户名称
... get().set()
public abstract void accept(Visitor visitor);
}
//企业客户
public class EnterpriseCustomer extends Customer{
private String linkman;//联系人
private String linkTelephone;//联系电话
private String registerAddress;//企业注册地址
public abstract void accept(Visitor visitor);
}
//个人客户
public class PersonalCustomer extends Customer{
private String telephone; //联系电话
private int age;//年龄
public void accept(Visitor visitor) {
//回调访问者对象的相应方法
visitor.visitPersonalCustomer(this);
}
}
//访问者接口
public interface Visitor {
//访问企业客户,相当于给企业客户添加访问者的功能
public void visitEnterpriseCustomer(EnterpriseCustomer ec);
//访问个人客户,相当于给个人客户添加访问者的功能
public void visitPersonalCustomer(PersonalCustomer pc);
}
public class WorthAnalyzeVisitor implements Visitor {
public void visitEnterpriseCustomer(EnterpriseCustomer ec){
//根据购买的金额大小、购买的产品和服务的多少、购买的频率等进行分析
//企业客户的标准会比个人客户的高
System.out.println("现在对企业客户"+ec.getName()+"进行价值分析");
}
public void visitPersonalCustomer(PersonalCustomer pc){
System.out.println("现在对个人客户"+pc.getName()+"进行价值分析");
}
}
public class ServiceRequestVisitor implements Visitor {
public void visitEnterpriseCustomer(EnterpriseCustomer ec){
//企业客户提出的具体服务请求
System.out.println(ec.getName()+"企业提出服务请求");
}
public void visitPersonalCustomer(PersonalCustomer pc){
//个人客户提出的具体服务请求
System.out.println("客户"+pc.getName()+"提出服务请求");
}
}
public class ObjectStructure {
//要操作的客户集合
private Collection<Customer> col = new ArrayList<Customer>();
//提供给客户端操作的高层接口,具体的功能由客户端传入的访问者决定
public void handleRequest(Visitor visitor){
//循环对象结构中的元素,接受访问
for(Customer cm : col){
cm.accept(visitor);
}
}
//组建对象结构,向对象结构中添加元素。
public void addElement(Customer ele){
this.col.add(ele);
}
}
public static void main(String[] args) {
//创建ObjectStruct
ObjectStructure os = new ObjectStructure();
//准备点测试数据,创建客户对象,并加入ObjectStructure
Customer cm1 = new EnterpriseCustomer();
cm1.setName("ABC集团");
os.addElement(cm1);
Customer cm2 = new EnterpriseCustomer();
cm2.setName("CDE公司");
os.addElement(cm2);
Customer cm3 = new PersonalCustomer();
cm3.setName("张三");
os.addElement(cm3);
//客户提出服务请求,传入服务请求的Visitor
ServiceRequestVisitor srVisitor = new ServiceRequestVisitor();
os.handleRequest(srVisitor);
//要对客户进行偏好分析,传入偏好分析的Visitor
PredilectionAnalyzeVisitor paVisitor = new PredilectionAnalyzeVisitor();
os.handleRequest(paVisitor);
//要对客户进行价值分析,传入价值分析的Visitor
WorthAnalyzeVisitor waVisitor = new WorthAnalyzeVisitor();
os.handleRequest(waVisitor);
}
2. 总结
1.访问者的功能
访问者模式能给一系列对象透明地添加新功能,从而避免在维护期间对这一系列对象进行修改,而且还能变相实现复用访问者所具有的功能。
由于是针对一系列对象的操作,这也导致,如果只想给一系列对象中的部分对象添加功能,就会有些麻烦;而且要始终能保证把这一系列对象都调用到,不管是循环,还是递归,总之要让每个对象都要被访问到。
2.调用通路
访问者之所以能实现“为一系列对象透明地添加新功能”,注意是透明的,也就是这一系列对象是不知道被添加功能的。
重要的就是依靠通用方法,访问者这边说要去访问,就提供一个访问的方法,如visit方法;而对象那边说,好的,我接受你的访问,提供一个接受访问的方法,如accept方法。这两个方法并不代表任何具体的功能,只是构成一个调用的通路,那么真正的功能实现在哪里呢?又如何调用到呢?
很简单,就在accept方法里面,回调visit的方法,从而回调到访问者的具体实现上,而这个访问者的具体实现的方法才是要添加的新的功