-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEmployeeRepository.java
More file actions
95 lines (84 loc) · 3.14 KB
/
Copy pathEmployeeRepository.java
File metadata and controls
95 lines (84 loc) · 3.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package Phase3_ObjectOrientation.EmployeeApp;
import java.util.*;
/**
* EmployeeRepository - the aggregate that owns the in-memory employee table.
* <p>
*
* Programs against the Employee INTERFACE rather than any specific record,
* which is the whole point of interface-driven design: the repository works
* unchanged no matter how many new permitted variants we add.
* <p>
*
* Demonstrates:
* - Programming to an interface (Employee).
* - Functional interfaces used as method parameters (EmployeeFilter).
* - Generic helpers constrained by capability markers (Auditable, Promotable).
*/
public class EmployeeRepository {
private final List<Employee> employees = new ArrayList<>();
/** Add an employee. Returns the same reference so callers can chain. */
public <E extends Employee> E add(E employee) {
employees.add(employee);
return employee;
}
/** Read-only view of all employees. */
public List<Employee> all() {
return Collections.unmodifiableList(employees);
}
/** Find the first employee matching a filter. */
public Optional<Employee> findFirst(EmployeeFilter filter) {
for (Employee e : employees) {
if (filter.accept(e)) return Optional.of(e);
}
return Optional.empty();
}
/** Find every employee matching a filter. */
public List<Employee> findAll(EmployeeFilter filter) {
List<Employee> result = new ArrayList<>();
for (Employee e : employees) {
if (filter.accept(e)) result.add(e);
}
return result;
}
/** Sum the monthly payroll across every employee. */
public double totalMonthlyPay() {
double sum = 0;
for (Employee e : employees) sum += e.monthlyPay();
return sum;
}
/**
* Audit only the employees that opted IN by implementing Auditable.
* Demonstrates how a marker interface lets us filter polymorphically.
*/
public void runAudit() {
System.out.println("\n--- audit log ---");
for (Employee e : employees) {
if (e instanceof Auditable) {
System.out.println("AUDIT " + e.summary());
}
}
}
/**
* Promote every employee that is Promotable, returning a NEW list of
* Employees with the raise applied. Records are immutable, so we model
* the promotion as a fresh object rather than mutating in place.
*/
public List<Employee> promoteEveryone(double percent) {
List<Employee> updated = new ArrayList<>();
for (Employee e : employees) {
if (e instanceof Promotable p) {
updated.add(p.promote(percent));
} else {
updated.add(e);
}
}
return updated;
}
/** Print a tidy table of all employees, sorted by annual salary. */
public void printRoster() {
System.out.println("\n--- roster (sorted by annual salary, desc) ---");
List<Employee> sorted = new ArrayList<>(employees);
sorted.sort(Comparator.comparingDouble(Employee::annualSalary).reversed());
for (Employee e : sorted) System.out.println(e.summary());
}
}