1.定义
- 目的是方便访问某种数据结构中的各个元素,在不改变此数据结构的前提下定义作用于这些元素的新的操作
2.UML类图
- 角色介绍
AbstractVisitor : 抽象访问者,定义对每一个Element的访问行为
ConcreteVisitor : 具体访问者, 实现具体访问行为
AbstractElement : 抽象元素类,定义接受AbstractVisitor访问的方法
ConcreteElement : 具体元素类
ObjectStructure : 对象结果,用于管理AbstractElement对象集合 - 要点
AbstractVisitor中定义了每个元素类的访问行为,所以此模式要求对象结果相对稳定,否则就做不到开闭原则
3.UML示例代码
/**
* Copyright (C), 2016-2020
* FileName: AbstractClub
* Author: wei.zheng
* Date: 2019/12/21 18:49
* Description: 俱乐部抽象类,AbstractElement角色
*/
public abstract class AbstractClub {
private String name;
private int payTaxes;
public AbstractClub(String name) {
this.name = name;
payTaxes = new Random().nextInt(100);
}
public String getName() {
return name;
}
public int getPayTaxes() {
return payTaxes;
}
public abstract void accept(AbstractVisitor visitor);
}
/**
* Copyright (C), 2016-2020
* FileName: FootballClub
* Author: wei.zheng
* Date: 2019/12/21 19:08
* Description: 足球俱乐部
*/
public class FootballClub extends AbstractClub {
private int championNum;
public FootballClub(String name) {
super(name);
championNum = new Random().nextInt(10);
}
public int getChampionNum() {
return championNum;
}
@Override
public void accept(AbstractVisitor visitor) {
visitor.visit(this);
}
}
/**
* Copyright (C), 2016-2020
* FileName: BasketballClub
* Author: wei.zheng
* Date: 2019/12/21 19:19
* Description: 篮球俱乐部
*/
public class BasketballClub extends AbstractClub {
private float attendanceRate;
public BasketballClub(String name) {
super(name);
attendanceRate = 0.88f;
}
public float getAttendanceRate() {
return attendanceRate;
}
@Override
public void accept(AbstractVisitor visitor) {
visitor.visit(this);
}
}
/**
* Copyright (C), 2016-2020
* FileName: AbstractVisitor
* Author: wei.zheng
* Date: 2019/12/21 18:53
* Description: 访问者抽象类
*/
public abstract class AbstractVisitor {
public abstract void visit(FootballClub club);
public abstract void visit(BasketballClub club);
}
/**
* Copyright (C), 2016-2020
* FileName: MayorVisitor
* Author: wei.zheng
* Date: 2019/12/21 18:55
* Description: 市长访问者, 关心足球俱乐部的冠军数量,关心篮球俱乐部的上座率
*/
public class MayorVisitor extends AbstractVisitor {
@Override
public void visit(FootballClub club) {
System.out.println("俱乐部:" + club.getName() + ", 冠军数量:" + club.getChampionNum());
}
@Override
public void visit(BasketballClub club) {
System.out.println("俱乐部:" + club.getName() + ", 上座率:" + club.getAttendanceRate());
}
}
/**
* Copyright (C), 2016-2020
* FileName: FinanceMinisterVisitor
* Author: wei.zheng
* Date: 2019/12/21 19:03
* Description: 财政部长访问者,关心俱乐部的缴税额
*/
public class FinanceMinisterVisitor extends AbstractVisitor {
@Override
public void visit(FootballClub club) {
System.out.println("俱乐部:" + club.getName() + ", 缴税额:" + club.getPayTaxes());
}
@Override
public void visit(BasketballClub club) {
System.out.println("俱乐部:" + club.getName() + ", 缴税额:" + club.getPayTaxes());
}
}
/**
* Copyright (C), 2016-2020
* FileName: VisitorReport
* Author: wei.zheng
* Date: 2019/12/21 19:31
* Description: 访问者报告类
*/
public class VisitorReport {
private List<AbstractClub> clubList = new ArrayList<>();
public VisitorReport() {
clubList.add(new FootballClub("广州恒大"));
clubList.add(new FootballClub("广州富力"));
clubList.add(new BasketballClub("广东宏远"));
}
public void showReport(AbstractVisitor visitor) {
for (AbstractClub club : clubList) {
club.accept(visitor);
}
}
}
/**
* Copyright (C), 2016-2020
* FileName: Client
* Author: wei.zheng
* Date: 2019/12/21 19:30
* Description: 访问者模式用户类
*/
public class Client {
public static void main(String[] args) {
VisitorReport report = new VisitorReport();
System.out.println("MayorVisitor 访问数据");
report.showReport(new MayorVisitor());
System.out.println("FinanceMinisterVisitor 访问数据");
report.showReport(new FinanceMinisterVisitor());
}
}
// 运行结果
2019-12-21 19:42:31.017 10473-10473/? I/System.out: MayorVisitor 访问数据
2019-12-21 19:42:31.018 10473-10473/? I/System.out: 俱乐部:广州恒大, 冠军数量:3
2019-12-21 19:42:31.018 10473-10473/? I/System.out: 俱乐部:广州富力, 冠军数量:4
2019-12-21 19:42:31.018 10473-10473/? I/System.out: 俱乐部:广东宏远, 上座率:0.88
2019-12-21 19:42:31.019 10473-10473/? I/System.out: FinanceMinisterVisitor 访问数据
2019-12-21 19:42:31.019 10473-10473/? I/System.out: 俱乐部:广州恒大, 缴税额:14
2019-12-21 19:42:31.019 10473-10473/? I/System.out: 俱乐部:广州富力, 缴税额:8
2019-12-21 19:42:31.020 10473-10473/? I/System.out: 俱乐部:广东宏远, 缴税额:37
4.总结
- 优缺点
优点:数据操作与数据结构分离
缺点:复杂
来源:CSDN
作者:wei.zheng
链接:https://blog.csdn.net/qq_37514242/article/details/103647700