@@@模式定义:
表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下

定义作用于这些元素的新操作。

@@@练习示例: 

扩展客户管理的功能

@@@示例代码:

\pattern\Customer.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);
}

\pattern\Visitor.java

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

package pattern;

/**
* 访问者接口
*/
public interface Visitor {
/**
* 访问企业客户,相当于给企业客户添加访问者的功能
* @param ec 企业客户的对象
*/
public void visitEnterpriseCustomer(EnterpriseCustomer ec); /**
* 访问个人客户,相当于给个人客户添加访问者的功能
* @param pc 个人客户的对象
*/
public void visitPersonalCustomer(PersonalCustomer pc);
}

\pattern\EnterpriseCustomer.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);
}
}

\pattern\PersonalCustomer.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);
}
}

\pattern\ServiceRequestVisitor.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() + "提出服务请求");
}
}

\pattern\PredilectionAnalyzeVisitor.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() + "进行产品偏好分析");
}
}

\pattern\ObjectStructure.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);
}
}

\user\Client.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

访问者模式(Visitor)的更多相关文章

  1. 设计模式 ( 二十 ) 访问者模式Visitor(对象行为型)

    设计模式 ( 二十 ) 访问者模式Visitor(对象行为型) 1.概述 在软件开发过程中,对于系统中的某些对象,它们存储在同一个集合collection中,且具有不同的类型,而且对于该集合中的对象, ...

  2. 乐在其中设计模式(C#) - 访问者模式(Visitor Pattern)

    原文:乐在其中设计模式(C#) - 访问者模式(Visitor Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 访问者模式(Visitor Pattern) 作者:webabc ...

  3. 访问者模式 Visitor 行为型 设计模式(二十七)

    访问者模式 Visitor    <侠客行>是当代作家金庸创作的长篇武侠小说,新版电视剧<侠客行>中,开篇有一段独白:  “茫茫海外,传说有座侠客岛,岛上赏善罚恶二使,每隔十年 ...

  4. 二十四种设计模式:访问者模式(Visitor Pattern)

    访问者模式(Visitor Pattern) 介绍表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 示例有一个Message实体类,某些对象对 ...

  5. 访问者模式(Visitor Pattern)——操作复杂对象结构

    模式概述 在软件开发中,可能会遇到操作复杂对象结构的场景,在该对象结构中存储了多个不同类型的对象信息,而且对同一对象结构中的元素的操作方式并不唯一,可能需要提供多种不同的处理方式,还有可能增加新的处理 ...

  6. 十一个行为模式之访问者模式(Visitor Pattern)

    定义: 提供一个作用于某对象结构(通常是一个对象集合)的操作的接口,使得在添加新的操作或者在添加新的元素时,不需要修改原有系统,就可以对各个对象进行操作. 结构图: Visitor:抽象访问者类,对元 ...

  7. C#设计模式——访问者模式(Visitor Pattern)

    一.概述由于需求的改变,某些类常常需要增加新的功能,但由于种种原因这些类层次必须保持稳定,不允许开发人员随意修改.对此,访问者模式可以在不更改类层次结构的前提下透明的为各个类动态添加新的功能.二.访问 ...

  8. [设计模式] 23 访问者模式 visitor Pattern

    在GOF的<设计模式:可复用面向对象软件的基础>一书中对访问者模式是这样说的:表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作.访问 ...

  9. 学习笔记——访问者模式Visitor

    访问者模式,通过Visitor的注入,为Element扩展了方法实现.虽然避免了Element不用修改即可修改,但却破坏了类的封装性,同时,一旦变更就需要增加子类,在子类方法中调用基类方法,然后再使用 ...

  10. 24访问者模式Visitor

    一.什么是访问者模式 Visitor模式也叫访问者模式,是行为模式之一 ,它分离对象的数据和行为,使用Visitor模式, 可以不修改已有类的情况下,增加新的操作. 二.访问者模式的应用示例 比如有一 ...

随机推荐

  1. JS字符串操作大全

    String对象属性 (1) length属性 length算是字符串中非常常用的一个属性了,它的功能是获取字符串的长度.当然需要注意的是js中的中文每个汉字也只代表一个字符,这里可能跟其他语言有些不 ...

  2. 什么XSS攻击?PHP防止XSS攻击函数

    什么XSS攻击?PHP防止XSS攻击函数 发布时间: 2013-05-14 浏览次数:22325 分类: PHP教程 XSS 全称为 Cross Site Scripting,用户在表单中有意或无意输 ...

  3. python基础之列表常用操作及知识点小结

    列表(list) List(列表) 是 Python 中使用最频繁的数据类型.列表可以完成大多数集合类的数据结构实现.它支持字符,数字,字符串甚至可以包含列表(所谓嵌套).列表用[ ]标识,是pyth ...

  4. ASP.NET MVC 中使用JavaScriptResult

    在浏览器地址栏输入地址,在页面上想通过脚本弹出一个框,看到Controller下有个JavaScript方法,返回的类型是JavaScriptResult,于是想用这个方法弹出框, public Ac ...

  5. 扩展原生js的一些方法

    扩展原生js的Array类 Array.prototype.add = function(item){ this.push(item); } Array.prototype.addRange = fu ...

  6. bzoj 1022: [SHOI2008]小约翰的游戏John anti_nim游戏

    1022: [SHOI2008]小约翰的游戏John Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1189  Solved: 734[Submit][ ...

  7. DPI/PPI/dp/sp/px/pt 移动设计手册

    转自DPI/PPI/dp/sp/px/pt 移动设计手册 做移动设计的同学,不管是原生app或者web app,应该对字体字号都是很头痛的问题.根本原因是,我们用唯一分辨率的电脑,设计各个不同尺寸大小 ...

  8. Delphi在win7/vista下写注册表等需要管理员权限的解决方案

    看到论坛好多人问win7下写注册表的问题,我结合自己的理解写了一点东西,首先声明一下,本人初学Delphi,水平有限,大家见笑了,有什么不对之处请老鸟多指点. [背景]win7/Vista提供的UAC ...

  9. RESTful, 说说 http 的 patch method

    最早的时候,我们只需要 GET 和 POST 方法,POST 方法的引入也只是为了消除 URL 过长,参数隐藏,上传文件的问题,完全和语义无关.接触到 RESTful 之后,我们开始思考 GET 和 ...

  10. Copying Linked Lists with Random Pointers

    Copying Linked Lists with Random Pointers 两个方法:方法一: 1.不考虑随机指针的情况下复制链表: 2.在复制过程中建立一个以原链表节点地址为key,相应的复 ...