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

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

@@@练习示例: 

扩展客户管理的功能

@@@示例代码:

\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. QT UI 使一个QWidget里面的元素自动填充满本QWidget

    使一个QWidget里面的元素自动填充满本QWidget: 对象查看器,右键点击本QWidget,选择"布局",为此QWidget增加一个布局. 如果该QWidget只有一个对象, ...

  2. Fatal error: Uncaught SoapFault exception

    Warning: SoapClient::SoapClient() expects parameter 2 to be array, boolean given in  login\login.php ...

  3. 转载C#泛型集合—Dictionary<K,V>使用技巧

    1.要使用Dictionary集合,需要导入C#泛型命名空间 System.Collections.Generic(程序集:mscorlib) 2.描述 1).从一组键(Key)到一组值(Value) ...

  4. C# 禁止 Webbrowser 控件的弹出脚本错误对话框

    当IE浏览器遇到脚本错误时浏览器,左下 角会出现一个黄色图标,点击可以查看脚本错误的详细信息,并不会有弹出的错误信息框.当我们使用 WebBrowser控件时有错误信息框弹出,这样程序显的很不友好,而 ...

  5. "The connection for the USB device '###' was unsuccessful. The device is currently in use"

    一.问题描述 1.情景描述 笔者的物理主机系统是“windows7 64位”,想使用“摄像头录像大师”.这个软件在录制视频的过程中,需要调用windows自带的"windows media ...

  6. SignalR介绍与Asp.net,前台即时通信【转】

    SignalR 是一个asp.net异步库,它提供广播消息到多个client端的机制. SignalR能用来持久客户端与服务端的连接,让我们便于开发一些实时的应用,例如聊天室在线预订系统,股票交易等实 ...

  7. CodeforcesGym101116 B Bulbs

    Description Greg has an \(m \times n\) grid of Sweet Lightbulbs of Pure Coolness he would like to tu ...

  8. Android 使用HTTP(get和post)方式登陆服务器

    package com.wuyou.submittoserver; import android.os.Bundle; import android.support.v7.app.ActionBarA ...

  9. qt5使用curl实现文件下载的示例程序 good

    http://blog.csdn.net/xueyushenzhou/article/details/51702672#t3 http://download.csdn.net/detail/xueyu ...

  10. spring 动态数据源

    1.动态数据源:  在一个项目中,有时候需要用到多个数据库,比如读写分离,数据库的分布式存储等等,这时我们要在项目中配置多个数据库. 2.原理:   (1).spring 单数据源获取数据连接过程: ...