定义

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

UML

优点

  1. 符合单一职责原则:凡是适用访问者模式的场景中,元素类中需要封装在访问者中的操作必定是与元素类本身关系不大且是易变的操作,使用访问者模式一方面符合单一职责原则,另一方面,因为被封装的操作通常来说都是易变的,所以当发生变化时,就可以在不改变元素类本身的前提下,实现对变化部分的扩展;
  2. 扩展性良好:元素类可以通过接受不同的访问者来实现对不同操作的扩展;
  3. 允许你对组合结构加入新的操作,无需改变结构本身;
  4. 想要加入新的操作相对容易;
  5. 访问者所进行的操作,其代码是集中在一起的。

缺点

  1. 会打破组合类的封装;
  2. 因为游走的功能牵涉其中,随意对组合结构的改变就更加困难。

应用场景

  1. 一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作;
  2. 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作“污染”这些对象的类。Visitor模式使得你可以将相关的操作集中起来定义在一个类中;
  3. 当该对象结构被很多应用共享时,用Visitor模式让每个应用仅包含需要用到的操作;
  4. 定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对所有访问者的接口,这可能需要很大的代价。如果对象结构类经常改变,那么可能还是在这些类中定义这些操作较好。

示例

通过访问者来访问不同对象并打印对应访问者刚兴趣的数据出来。

Java

 import java.util.ArrayList;
import java.util.List; public class Main
{
public static void main(String[] args)
{
List<Employee> list = new ArrayList<>(); CommonEmployee zhangSan = new CommonEmployee();
zhangSan.setName("张三");
zhangSan.setSex(Employee.MALE);
zhangSan.setSalary(5000);
zhangSan.setJob("苦逼的码农");
list.add(zhangSan); CommonEmployee liSi = new CommonEmployee();
liSi.setName("李四");
liSi.setSex(Employee.FEMALE);
liSi.setSalary(20000);
liSi.setJob("公司里唯一的程序媛");
list.add(liSi); Manager wangWu = new Manager();
wangWu.setName("王五");
wangWu.setSex(Employee.MALE);
wangWu.setSalary(66000);
wangWu.setPerformance("业绩基本为负值,不过每次马屁都拍得老板很飘!");
list.add(wangWu); for (Employee em : list)
{
em.accept(new Visitor());
}
} /**
* 访问者接口
*/
public interface IVisitor
{
/**
* 访问普通员工
*/
void visit(CommonEmployee commonEmployee); /**
* 访问经理
*/
void visit(Manager manager);
} /**
* 访问者对象
*/
public static class Visitor implements IVisitor
{
@Override
public void visit(CommonEmployee commonEmployee)
{
System.out.println(getCommonEmployee(commonEmployee));
} @Override
public void visit(Manager manager)
{
System.out.println(getManagerInfo(manager));
} private String getBasicInfo(Employee employee)
{
String info = "姓名:" + employee.getName() + "\t";
info += "性别:" + (employee.getSex() == Employee.MALE ? "男" : "女") + "\t";
info += "薪水:" + employee.getSalary() + "\t";
return info;
} private String getCommonEmployee(CommonEmployee commonEmployee)
{
String basicInfo = getBasicInfo(commonEmployee);
String otherInfo = "工作:" + commonEmployee.getJob();
return basicInfo + otherInfo;
} private String getManagerInfo(Manager manager)
{
String basicInfo = getBasicInfo(manager);
String otherInfo = "业绩:" + manager.getPerformance();
return basicInfo + otherInfo;
}
} /**
* 员工基类
*/
public static abstract class Employee
{
public final static int MALE = 0; public final static int FEMALE = 1; private String name;
private int sex;
private int salary; public String getName()
{
return name;
} public void setName(String name)
{
this.name = name;
} public int getSex()
{
return sex;
} public void setSex(int sex)
{
this.sex = sex;
} public int getSalary()
{
return salary;
} public void setSalary(int salary)
{
this.salary = salary;
} /**
* 接受访问者访问
*/
public abstract void accept(IVisitor visitor);
} /**
* 普通员工
*/
public static class CommonEmployee extends Employee
{
private String job; public String getJob()
{
return job;
} public void setJob(String job)
{
this.job = job;
} @Override
public void accept(IVisitor visitor)
{
visitor.visit(this);
}
} /**
* 经理
*/
public static class Manager extends Employee
{
private String performance; public String getPerformance()
{
return performance;
} public void setPerformance(String performance)
{
this.performance = performance;
} @Override
public void accept(IVisitor visitor)
{
visitor.visit(this);
}
}
}

行为类模式(十一):访问者(Visitor)的更多相关文章

  1. C#设计模式之二十一访问者模式(Visitor Pattern)【行为型】

    一.引言 今天我们开始讲“行为型”设计模式的第九个模式,该模式是[访问者模式],英文名称是:Visitor Pattern.如果按老规矩,先从名称上来看看这个模式,我根本不能获得任何对理解该模式有用的 ...

  2. 设计模式-访问者(Visitor)模式

    访问者模式是对象的行为模式.访问者模式的目的是封装施加在某种数据结构元素上的操作.一旦一些操作需要修改,接受这个操作的数据结构可以保持不变. 个人觉得访问者模式相对其他的设计模式来说稍微复杂,难理解一 ...

  3. Visitor模式(访问者设计模式)

    Visitor ? 在Visitor模式中,数据结构与处理被分离开来.我们编写一个表示"访问者"的类来访问数据结构中的元素, 并把对各元素的处理交给访问者类.这样,当需要增加新的处 ...

  4. 行为型模式(九) 访问者模式(Visitor)

    一.动机(Motivate) 在软件构建过程中,由于需求的改变,某些类层次结构中常常需要增加新的行为(方法),如果直接在基类中做这样的更改,将会给子类带来很繁重的变更负担,甚至破坏原有设计.如何在不更 ...

  5. [设计模式]访问者 Visitor 模式

    访问者模式是对象的行为模式. 访问者模式的目的是封装一些施加于某种数据结构元素之上的操作.一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变.

  6. GoF23种设计模式之行为型模式之访问者模式

    概述 表示一个作用于某对象结构中的各元素的操作. 它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 适用性 1.一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依 ...

  7. 设计模式之行为类模式大PK

                                        行为类模式大PK 行为类模式包括责任链模式.命令模式.解释器模式.迭代器模式.中介者模式.备忘录模式.观察者模式.状态模式.策略 ...

  8. 结构类模式(七):代理(Proxy)

    定义 为其他对象提供一种代理以控制对这个对象的访问. 代理模式也叫做委托模式,它是一项基本设计技巧.许多其他的模式,如状态模式.策略模式.访问者模式本质上是在更特殊的场合采用了委托模式,而且在日常的应 ...

  9. 设计模式之行为类模式PK

    行为类模式包括: 责任链模式 命令模式 解释器模式 迭代器模式 中介者模式 备忘录模式 观察者模式 状态模式 策略模式 模板方法模式 访问者模式 行为型模式涉及到算法和对象间职责的分配 行为类模式关注 ...

  10. 行为型模式(十一) 解释器模式(Interpreter)

    一.动机(Motivate) 在软件构建过程中,如果某一特定领域的问题比较复杂,类似的模式不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变化.在这种情况下,将特定领域的问题表达为某种语法规 ...

随机推荐

  1. [转]文件后缀与Mime类型对照表

    //文档文件类型的 .ai application/postscript .eps application/postscript .exe application/octet-stream .doc ...

  2. python3新特点

    #xiaodeng #python 3 #1.编码方式和性能 ''' 1.py3运行效率更快 2.默认源文件编码ASCII变为UTF-8,以前文件前加入的coding=utf-8不再需要 3.针对un ...

  3. Citrix Port(常用端口)

    组件 类型 端口 描述 CitrixLicenseServer       许可管理器守护程序 TCP 27000 处理初始接触点的许可证要求(Lmadmin.exe) 思杰供应商守护程序 TCP 7 ...

  4. 今天才明白VC++.net的含义: VS系列的c++编译器可以支持托管C++(类似于C#,具体请看MS在线文档),当然包括winform界面开发。

    因此我决定用winform做界面,用C++写逻辑.当然尽量不用托管代码写逻辑.

  5. H5商城,纯前端静态页面

    发布时间:2018-09-28   技术:jquery1.10.1+swipeSlide+jquery.mmenu+jquery.touchSwipe+cityinit   概述 纯手写H5商城,2年 ...

  6. 安全删除linux旧内核的方法

    我们在用yum升级系统之后,希望往往会为我们保持旧的内核文件,这样以防在出现硬件或者软件冲突的时候我们能够返回到旧的内核文件继续使用,如果我们想要安全的删除旧的内核文件,可以follow下面的方法. ...

  7. oracle安装后tnsnames.ora内容

    # tnsnames.ora Network Configuration File: D:\Develop\oracle11g\product\11.2.0\dbhome_1\network\admi ...

  8. 你真的了解字典(Dictionary)吗? C# Memory Cache 踩坑记录 .net 泛型 结构化CSS设计思维 WinForm POST上传与后台接收 高效实用的.NET开源项目 .net 笔试面试总结(3) .net 笔试面试总结(2) 依赖注入 C# RSA 加密 C#与Java AES 加密解密

    你真的了解字典(Dictionary)吗?   从一道亲身经历的面试题说起 半年前,我参加我现在所在公司的面试,面试官给了一道题,说有一个Y形的链表,知道起始节点,找出交叉节点.为了便于描述,我把上面 ...

  9. cucumber java从入门到精通(3)简单实现及断言

    cucumber java从入门到精通(3)简单实现及断言 上一节里我们定义了step的java代码实现文件,step就是测试步骤及断言的集合,我们先定义出来,以后可以驱动开发以及在持续集成时重用. ...

  10. C++编程技巧降低编译时间

    1. #define的保护 全部头文件都应该使用#define 防止头文件被多重包括(multiple inclusion).命名格式 当是:<PROJECT>_<PATH>_ ...