Java Visitor Pattern Example: Managing Employee Access Across Departments in an OA System
This article explains the Visitor design pattern, illustrates its structure, and provides a complete Java implementation that lets HR and finance departments process full‑time and part‑time employee data in an OA system without modifying existing classes.
Scenario
The Visitor pattern is a behavioral design pattern that separates operations from the object structure they act upon. In an OA system, employee records (full‑time and part‑time) form the object structure, while HR and finance departments act as visitors that need to perform different calculations such as work‑time aggregation and wage computation.
Visitor Pattern Structure
The pattern consists of the following roles:
Visitor (abstract) : declares a set of visit methods for each concrete element type.
ConcreteVisitor : implements the visit methods; in this example FADepartment (finance) and HRDepartment (human resources).
Element (abstract) : defines an accept(Visitor) method.
ConcreteElement : concrete employee classes ( FulltimeEmployee and ParttimeEmployee) that implement accept by invoking the appropriate visitor method.
ObjectStructure : EmployeeList stores a collection of Employee objects and provides an accept method that iterates over the collection, allowing a visitor to process each element.
Implementation
Key interfaces and classes are shown below.
interface Employee {
// Accept a visitor
void accept(Department handler);
} public class FulltimeEmployee implements Employee {
private String name;
private double weeklyWage;
private int workTime;
// constructors, getters, setters omitted for brevity
@Override
public void accept(Department handler) {
handler.visit(this);
}
} public class ParttimeEmployee implements Employee {
private String name;
private double hourWage;
private int workTime;
// constructors, getters, setters omitted for brevity
@Override
public void accept(Department handler) {
handler.visit(this);
}
} abstract class Department {
public abstract void visit(FulltimeEmployee employee);
public abstract void visit(ParttimeEmployee employee);
} public class FADepartment extends Department {
@Override
public void visit(FulltimeEmployee employee) {
int workTime = employee.getWorkTime();
double weekWage = employee.getWeeklyWage();
if (workTime > 40) {
weekWage += (workTime - 40) * 100;
} else if (workTime < 40) {
weekWage -= (40 - workTime) * 80;
if (weekWage < 0) weekWage = 0;
}
System.out.println("正式员工" + employee.getName() + "实际工资为:" + weekWage);
}
@Override
public void visit(ParttimeEmployee employee) {
System.out.println("临时工" + employee.getName() + "实际工资为:" + employee.getWorkTime() * employee.getHourWage());
}
} public class HRDepartment extends Department {
@Override
public void visit(FulltimeEmployee employee) {
int workTime = employee.getWorkTime();
System.out.println("正式员工" + employee.getName() + "实际工作时间:" + workTime);
if (workTime > 40) {
System.out.println("正式员工" + employee.getName() + "加班时间为" + (workTime - 40));
} else if (workTime < 40) {
System.out.println("正式员工" + employee.getName() + "请假时间为" + (40 - workTime));
}
}
@Override
public void visit(ParttimeEmployee employee) {
System.out.println("临时工" + employee.getName() + "实际工作时间:" + employee.getWorkTime());
}
} import java.util.ArrayList;
public class EmployeeList {
private ArrayList<Employee> list = new ArrayList<>();
public void addEmployee(Employee employee) { list.add(employee); }
public void accept(Department handler) {
for (Employee e : list) {
e.accept(handler);
}
}
} public class Client {
public static void main(String[] args) {
EmployeeList list = new EmployeeList();
list.addEmployee(new FulltimeEmployee("张三", 1200, 40));
list.addEmployee(new FulltimeEmployee("李四", 1500, 30));
list.addEmployee(new FulltimeEmployee("王五", 2000, 50));
list.addEmployee(new ParttimeEmployee("赵六", 50, 10));
list.addEmployee(new ParttimeEmployee("周七", 90, 20));
System.out.println("实现财务部门的访问");
Department dep = new FADepartment();
list.accept(dep);
System.out.println("实现人力部门的访问");
dep = new HRDepartment();
list.accept(dep);
}
}The program produces output showing each employee's calculated wage (finance visitor) and recorded work time, overtime, or leave (HR visitor). The result image is shown below.
Discussion on Extensibility
Adding a new visitor (e.g., a new department) requires only creating a new concrete visitor class that implements the existing visit methods; the existing element classes remain unchanged, demonstrating compliance with the Open/Closed Principle for visitor extensions.
Conversely, adding a new element type (e.g., a retired employee) necessitates modifying the abstract visitor ( Department) to declare a new visit method and updating all existing concrete visitors, which violates the Open/Closed Principle for element extensions. The article concludes that the Visitor pattern, like the Abstract Factory pattern, favors adding new operations over adding new element types.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
The Dominant Programmer
Resources and tutorials for programmers' advanced learning journey. Advanced tracks in Java, Python, and C#. Blog: https://blog.csdn.net/badao_liumang_qizhi
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
