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

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

@@@练习示例: 

扩展客户管理的功能

@@@示例代码:

\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. Android Studio中JNI -- 1 -- 配置方法

    1.配置NDK 1.1 下载NDK Android Studio 1.2 配 android-ndk-r10e,不同版本的Studio需要配置不同的ndk,下载完成后,随便解压放至某个文件目录下 1. ...

  2. IE9透明filter和opacity同时生效的解决办法 IE9 hack only

    转载请注明:来自于http://www.cnblogs.com/bluers/ 问题: 假设结构如下: <div class="wrapper"> <p clas ...

  3. JQuery slideToggle闪烁问题及解决办法

    在使用slideToggle的时候,会出现在实现隐藏效果后闪烁一下在消失,找了很多原因,本以为是浏览器问题,后来发现是文档定义类型的问题... 原来页面的文档定义:<!DOCTYPE HTML ...

  4. [Linux]Ubuntu下如何将普通用户提升到root权限

    转至:http://jingyan.baidu.com/album/6181c3e0780131152ef153ff.html?picindex=0&qq-pf-to=pcqq.c2c  在u ...

  5. 精通 Oracle+Python,第 8 部分:适合 Oracle DBA 使用的 Python

    传统上,当需要为操作系统编写一些脚本时,人们常常会选用 Bash 或 Perl 脚本工具.这些工具易于使用,因而它们几乎变得无处不在,渗透到了包括 Oracle Database 在内的其他软件中,O ...

  6. 【C语言】测试系统各数据类型大小代码

    测试各系统不同数据类型大小代码 一.相关基础知识 不同环境下各数据类型大小可能不相等,(某些环境下,类型带下可以选择)故测了就知道! 二.具体内容 三.分析总结 四.实例测试 #include< ...

  7. WCF SOAP

    WCF SOAP服务端解析 ASP.NET Core中间件(Middleware)进阶学习实现SOAP 解析. 本篇将介绍实现ASP.NET Core SOAP服务端解析,而不是ASP.NET Cor ...

  8. [Kinect]XBox One Kinect连接Windows

    注:本文全原创,作者:Noah Zhang  (http://www.cnblogs.com/noahzn/) XBox One带体感套装去年就买了,昨天京东349元入了个适配器,下午就送到了,开箱. ...

  9. C语言中exit()与return的区别

    整理自exit函数和return函数 1.exit函数和return函数的主要区别是: 1)exit用于在程序运行的过程中随时结束程序,exit的参数是返回给OS的.main函数结束时也会隐式地调用e ...

  10. Palindrome

    poj3974:http://poj.org/problem?id=3974 题意:求给定长度最长回文串的长度. 题解:直接套manacher,搞定. #include<iostream> ...