首页 技术 正文
技术 2022年11月20日
0 收藏 721 点赞 3,997 浏览 3112 个字

定义

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

UML

行为类模式(十一):访问者(Visitor)

优点

  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);
}
}
}
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,955
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,479
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,291
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,108
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,740
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,775