@@@模式定义:
表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下
定义作用于这些元素的新操作。
@@@练习示例:
扩展客户管理的功能
@@@示例代码:
patternCustomer.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package pattern; 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); }
patternVisitor.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package pattern; /** * 访问者接口 */ public interface Visitor { /** * 访问企业客户,相当于给企业客户添加访问者的功能 * @param ec 企业客户的对象 */ public void visitEnterpriseCustomer(EnterpriseCustomer ec); /** * 访问个人客户,相当于给个人客户添加访问者的功能 * @param pc 个人客户的对象 */ public void visitPersonalCustomer(PersonalCustomer pc); }
patternEnterpriseCustomer.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package pattern; 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; } @Override public void accept(Visitor visitor) { // 回调访问者对象的相应方法 visitor.visitEnterpriseCustomer(this); } }
patternPersonalCustomer.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package pattern; public class PersonalCustomer extends Customer { private String telephone; private String age; public String getTelephone() { return telephone; } public void setTelephone(String telephone) { this.telephone = telephone; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } @Override public void accept(Visitor visitor) { // 回调访问者对象的相应方法 visitor.visitPersonalCustomer(this); } }
patternServiceRequestVisitor.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package pattern; /** * 具体的访问者,实现客户提出服务请求的功能 */ public class ServiceRequestVisitor implements Visitor { @Override public void visitEnterpriseCustomer(EnterpriseCustomer ec) { // 企业客户提出的具体服务请求 System.out.println(ec.getName() + "企业提出服务请求"); } @Override public void visitPersonalCustomer(PersonalCustomer pc) { // 个人客户提出的具体服务请求 System.out.println("客户" + pc.getName() + "提出服务请求"); } }
patternPredilectionAnalyzeVisitor.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package pattern; /** * 具体的访问者,实现对客户的偏好分析 */ public class PredilectionAnalyzeVisitor implements Visitor { @Override public void visitEnterpriseCustomer(EnterpriseCustomer ec) { // 根据以往购买的历史、潜在购买意向 // 以及客户所在行业的发展趋势、客户的发展预期等的分析 System.out.println("现在对企业客户" + ec.getName() + "进行产品偏好分析"); } @Override public void visitPersonalCustomer(PersonalCustomer pc) { System.out.println("现在对个人客户" + pc.getName() + "进行产品偏好分析"); } }
patternObjectStructure.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package pattern; import java.util.ArrayList; import java.util.Collection; 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); } }
userClient.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package user; import pattern.Customer; import pattern.EnterpriseCustomer; import pattern.ObjectStructure; import pattern.PersonalCustomer; import pattern.PredilectionAnalyzeVisitor; import pattern.ServiceRequestVisitor; public class Client { public static void main(String[] args) { // 创建ObjectStructure 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); } }
@@@运行结果:
ABC集团企业提出服务请求
CDE公司企业提出服务请求
客户张三提出服务请求
现在对企业客户ABC集团进行产品偏好分析
现在对企业客户CDE公司进行产品偏好分析
现在对个人客户张三进行产品偏好分析
@@@模式的实现:
有一个调用回路,进行了两次分发。
@@@模式的优点:
好的扩展性;
好的复用性;
分离无关行为;
@@@模式的缺点:
对象结构变化很困难;
破环封装;
@@@模式的本质:
预留通路,回调实现。
@@@模式体现的设计原则:
NA