定义:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
本质:预留通路,回调实现。
不合理的解决方案:
假设需要增加以下功能:
1) 客户对公司产品的偏好分析;
2) 客户价值分析。
合理的解决方案:
package cn.javass.dp.visitor.example3;
/**
* 访问者接口
*/
public interface Visitor {
/**
* 访问元素A,相当于给元素A添加访问者的功能
* @param elementA 元素A的对象
*/
public void visitConcreteElementA(ConcreteElementA elementA);
/**
* 访问元素B,相当于给元素B添加访问者的功能
* @param elementB 元素B的对象
*/
public void visitConcreteElementB(ConcreteElementB elementB);
}
package cn.javass.dp.visitor.example3;
/**
* 被访问的元素的接口
*/
public abstract class Element {
/**
* 接受访问者的访问
* @param visitor 访问者对象
*/
public abstract void accept(Visitor visitor);
}
package cn.javass.dp.visitor.example3;
/**
* 具体元素的实现对象
*/
public class ConcreteElementA extends Element {
public void accept(Visitor visitor) {
//回调访问者对象的相应方法
visitor.visitConcreteElementA(this);
}
/**
* 示例方法,表示元素已有的功能实现
*/
public void opertionA() {
//已有的功能实现
}
}
package cn.javass.dp.visitor.example3;
/**
* 具体元素的实现对象
*/
public class ConcreteElementB extends Element {
public void accept(Visitor visitor) {
//回调访问者对象的相应方法
visitor.visitConcreteElementB(this);
}
/**
* 示例方法,表示元素已有的功能实现
*/
public void opertionB() {
//已有的功能实现
}
}
package cn.javass.dp.visitor.example3;
/**
* 具体的访问者实现
*/
public class ConcreteVisitor1 implements Visitor {
public void visitConcreteElementA(ConcreteElementA element) {
//把去访问ConcreteElementA时,需要执行的功能实现在这里
//可能需要访问元素已有的功能,比如:
element.opertionA();
}
public void visitConcreteElementB(ConcreteElementB element) {
//把去访问ConcreteElementB时,需要执行的功能实现在这里
//可能需要访问元素已有的功能,比如:
element.opertionB();
}
}
package cn.javass.dp.visitor.example3;
/**
* 具体的访问者实现
*/
public class ConcreteVisitor2 implements Visitor {
public void visitConcreteElementA(ConcreteElementA element) {
//把去访问ConcreteElementA时,需要执行的功能实现在这里
//可能需要访问元素已有的功能,比如:
element.opertionA();
}
public void visitConcreteElementB(ConcreteElementB element) {
//把去访问ConcreteElementB时,需要执行的功能实现在这里
//可能需要访问元素已有的功能,比如:
element.opertionB();
}
}
package cn.javass.dp.visitor.example3;
import java.util.*;
/**
* 对象结构,通常在这里对元素对象进行遍历,让访问者能访问到所有的元素
*/
public class ObjectStructure {
/**
* 示意,表示对象结构,可以是一个组合结构或是集合
*/
private Collection<Element> col = new ArrayList<Element>();
/**
* 示意方法,提供给客户端操作的高层接口
* @param visitor 客户端需要使用的访问者
*/
public void handleRequest(Visitor visitor){
//循环对象结构中的元素,接受访问
for(Element ele : col){
ele.accept(visitor);
}
}
/**
* 示意方法,组建对象结构,向对象结构中添加元素。
* 不同的对象结构有不同的构建方式
* @param ele 加入到对象结构的元素
*/
public void addElement(Element ele){
this.col.add(ele);
}
}
package cn.javass.dp.visitor.example3;
public class Client {
public static void main(String[] args) {
//创建ObjectStructure
ObjectStructure os = new ObjectStructure();
//创建要加入对象结构的元素
Element eleA = new ConcreteElementA();
Element eleB = new ConcreteElementB();
//把元素加入对象结构
os.addElement(eleA);
os.addElement(eleB);
//创建访问者
Visitor visitor = new ConcreteVisitor1();
//调用业务处理的方法
os.handleRequest(visitor);
}
}
package cn.javass.dp.visitor.example4;
/**
* 访问者接口
*/
public interface Visitor {
/**
* 访问企业客户,相当于给企业客户添加访问者的功能
*
* @param ec 企业客户的对象
*/
public void visitEnterpriseCustomer(EnterpriseCustomer ec);
/**
* 访问个人客户,相当于给个人客户添加访问者的功能
*
* @param pc 个人客户的对象
*/
public void visitPersonalCustomer(PersonalCustomer pc);
}
package cn.javass.dp.visitor.example4;
/**
* 各种客户的父类
*/
public abstract class Customer {
/**
* 客户编号
*/
private String customerId;
/**
* 客户名称
*/
private String name;
public String getCustomerId() {
return customerId;
}
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* 接受访问者的访问
*
* @param visitor 访问者对象
*/
public abstract void accept(Visitor visitor);
}
package cn.javass.dp.visitor.example4;
/**
* 企业客户
*/
public class EnterpriseCustomer extends Customer {
/**
* 联系人
*/
private String linkman;
/**
* 联系电话
*/
private String linkTelephone;
/**
* 企业注册地址
*/
private String registerAddress;
public String getLinkman() {
return linkman;
}
public void setLinkman(String linkman) {
this.linkman = linkman;
}
public String getLinkTelephone() {
return linkTelephone;
}
public void setLinkTelephone(String linkTelephone) {
this.linkTelephone = linkTelephone;
}
public String getRegisterAddress() {
return registerAddress;
}
public void setRegisterAddress(String registerAddress) {
this.registerAddress = registerAddress;
}
public void accept(Visitor visitor) {
//回调访问者对象的相应方法
visitor.visitEnterpriseCustomer(this);
}
}
package cn.javass.dp.visitor.example4;
/**
* 个人客户
*/
public class PersonalCustomer extends Customer {
/**
* 联系电话
*/
private String telephone;
/**
* 年龄
*/
private int age;
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void accept(Visitor visitor) {
//回调访问者对象的相应方法
visitor.visitPersonalCustomer(this);
}
}
package cn.javass.dp.visitor.example4;
/**
* 具体的访问者,实现客户提出服务请求的功能
*/
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() + "提出服务请求");
}
}
package cn.javass.dp.visitor.example4;
/**
* 具体的访问者,实现对客户价值分析
*/
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() + "进行价值分析");
}
}
package cn.javass.dp.visitor.example4;
/**
* 具体的访问者,实现对客户的偏好分析
*/
public class PredilectionAnalyzeVisitor implements Visitor {
public void visitEnterpriseCustomer(EnterpriseCustomer ec) {
//根据过往购买的历史、潜在购买意向
//以及客户所在行业的发展趋势、客户的发展预期等的分析
System.out.println("现在对企业客户" + ec.getName() + "进行产品偏好分析");
}
public void visitPersonalCustomer(PersonalCustomer pc) {
System.out.println("现在对个人客户" + pc.getName() + "进行产品偏好分析");
}
}
package cn.javass.dp.visitor.example4;
import java.util.*;
/**
* 对象结构,通常在这里对元素对象进行遍历,让访问者能访问到所有的元素
*/
public class ObjectStructure {
/**
* 要操作的客户集合
*/
private Collection<Customer> col = new ArrayList<Customer>();
/**
* 提供给客户端操作的高层接口,具体的功能由客户端传入的访问者决定
*
* @param visitor 客户端需要使用的访问者
*/
public void handleRequest(Visitor visitor) {
//循环对象结构中的元素,接受访问
for (Customer cm : col) {
cm.accept(visitor);
}
}
/**
* 组建对象结构,向对象结构中添加元素。
* 不同的对象结构有不同的构建方式
*
* @param ele 加入到对象结构的元素
*/
public void addElement(Customer ele) {
this.col.add(ele);
}
}
package cn.javass.dp.visitor.example4;
public class Client {
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);
}
}