定义
- 封装作用于某数据结构(如List,Set,Map等)中的各个操作。
- 可以在不改变各元素的类的前提下,定义作用于这些元素的操作。
适用场景
- 数据结构和数据操作分离。
- 一个数据结构包含多个类对象的时候。
优点
- 增加新的操作很容易,即增加一个新的访问者。
缺点
- 增加新的数据结构困难。
- 具体元素的变更比较麻烦。
代码
我们来实现一个简单的业务场景加深理解
在我们工作中,有时候难免会遇到出差的状况,那么大部分公司针对员工等级不同,出差报销的额度也不同。我们现在就定义三个等级的报销额度,然后拿代码实现以下具体业务。
员工等级
- 普通员工:基本差旅费报销
- 部门领导:基本差旅费报销+ 补助
- 管理层:基本差旅费报销+补助+升舱
这样 三个不同的对象就产生了。我们拿访问者模式搞一下。
访问者接口(IVisitor
)
/**
* 访问接口
*/
public interface IVisitor {
void visit(Employee employee);
}
员工抽象类(Employee
)
/**
* 员工抽象类
*/
public abstract class Employee {
//等级名称
private String levelName;
//基础福利
private String basic;
public abstract void accept(IVisitor visitor);
}
普通员工(NormalEmployee
)
/**
* 普通员工
*/
public class NormalEmployee extends Employee {
@Override
public void accept(IVisitor visitor) {
visitor.visit(this);
}
}
部门领导(DepartmentEmployee
)
public class DepartmentEmployee extends Employee {
@Override
public void accept(IVisitor visitor) {
visitor.visit(this);
}
}
管理层(LeaderEmployee
)
public class LeaderEmployee extends Employee {
@Override
public void accept(IVisitor visitor) {
visitor.visit(this);
}
}
访问者接口实现类
public class Visitor implements IVisitor {
@Override
public void visit(NormalEmployee employee) {
System.out.println(employee.getLevelName()+"出差报销规则"+ employee.getBasic());
}
@Override
public void visit(DepartmentEmployee employee) {
System.out.println(employee.getLevelName()+"出差报销规则"+ employee.getBasic() + employee.getAllowance());
}
@Override
public void visit(LeaderEmployee employee) {
System.out.println(employee.getLevelName()+"出差报销规则"+ employee.getBasic()+ employee.getAllowance() + employee.getUpgrade());
}
}
UML类图
visitorUML.jpg测试类
public class VisitorTest {
public static void main(String[] args) {
//----------普通员工---------
NormalEmployee normal = new NormalEmployee();
normal.setLevelName("普通员工");
normal.setBasic("基本差旅费报销");
//--------部门领导---------
DepartmentEmployee department = new DepartmentEmployee();
department.setBasic("基本差旅费报销");
department.setLevelName("部门领导");
department.setAllowance("餐补,交通补助");
//-----管理层-----
LeaderEmployee leader = new LeaderEmployee();
leader.setBasic("基本差旅费报销");
leader.setLevelName("管理层");
leader.setAllowance("餐补,交通补助");
leader.setUpgrade("飞机头等舱,火车一等座,酒店五星级");
List<Employee> list = new ArrayList<>();
list.add(normal);
list.add(department);
list.add(leader);
//访问这些对象的操作
for (Employee employee : list) {
employee.accept(new Visitor());
}
}
}
输出结果:
visitorResult.jpg小结
虽然访问者模式用的比较少,但是作为设计模式的一种,我们也需要熟悉理解。
网友评论