[Cracking Coding Problems] OOP
Call Center:
Imagine you have a call center with three levels of employees: respondent, manager, and director. An incoming telephone call must be first allocated to a respondent who is free
If the respondent can’t handle the call, he or she must escalate the call to a manager. If the manager is not free or not able to handle it, then the call should be escalated to a director
Design the classes and data structures for this problem. Implement a method dispatchCall() which assigns a call to the first available employee
Approach
Employees have 3 different roles. But the task(
handling call
) is the same. So, It is reusableUsing
Deque
enables efficient queuing
Prerequisite
- Java
Java
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import java.util.ArrayDeque;
import java.util.Deque;
class Call {
private String caller;
private Employee handler;
public Call(String caller) {
this.caller = caller;
this.handler = null;
}
public String getCaller() {
return caller;
}
public Employee getHandler() {
return handler;
}
public void setHandler(Employee handler) {
if (handler == null) {
throw new IllegalArgumentException("Handler cannot be null");
}
this.handler = handler;
}
}
abstract class Employee {
private String name;
private String rank; // respondent, manager, director
private boolean isFree;
public Employee(String name, String rank) {
this.name = name;
this.rank = rank;
this.isFree = true;
}
public boolean isFree() {
return isFree;
}
public void handleCall(Call call) {
this.isFree = false;
call.setHandler(this);
System.out.println(this.rank.substring(0, 1).toUpperCase() + this.rank.substring(1)
+ " " + this.name + " is handling the call from " + call.getCaller() + ".");
}
public void finishCall() {
this.isFree = true;
System.out.println(this.rank.substring(0, 1).toUpperCase() + this.rank.substring(1)
+ " " + this.name + " is now free.");
}
}
class Respondent extends Employee {
public Respondent(String name) {
super(name, "respondent");
}
}
class Manager extends Employee {
public Manager(String name) {
super(name, "manager");
}
}
class Director extends Employee {
public Director(String name) {
super(name, "director");
}
}
class CallCenter {
private Deque<Respondent> respondents;
private Deque<Manager> managers;
private Deque<Director> directors;
public CallCenter() {
this.respondents = new ArrayDeque<>();
this.managers = new ArrayDeque<>();
this.directors = new ArrayDeque<>();
}
public void addEmployee(Employee employee) {
if (employee instanceof Respondent) {
respondents.add((Respondent) employee);
} else if (employee instanceof Manager) {
managers.add((Manager) employee);
} else if (employee instanceof Director) {
directors.add((Director) employee);
}
}
public void dispatchCall(Call call) {
for (Deque<? extends Employee> queue : new Deque[]{respondents, managers, directors}) {
for (Employee employee : queue) {
if (employee.isFree()) {
employee.handleCall(call);
return;
}
}
}
System.out.println("No employees are available to handle the call from " + call.getCaller() + ". Call is in queue.");
}
public void releaseEmployee(Employee employee) {
employee.finishCall();
}
}
public class Main {
public static void main(String[] args) {
CallCenter callCenter = new CallCenter();
// Add employees
callCenter.addEmployee(new Respondent("Alice"));
callCenter.addEmployee(new Respondent("Bob"));
callCenter.addEmployee(new Manager("Charlie"));
callCenter.addEmployee(new Director("Diana"));
// Incoming calls
Call call1 = new Call("John Doe");
Call call2 = new Call("Jane Smith");
Call call3 = new Call("Customer X");
callCenter.dispatchCall(call1); // Alice handles the call
callCenter.dispatchCall(call2); // Bob handles the call
callCenter.dispatchCall(call3); // Charlie handles the call (escalated)
callCenter.releaseEmployee(call1.getHandler());
callCenter.releaseEmployee(call2.getHandler());
callCenter.releaseEmployee(call3.getHandler());
Call call4 = new Call("Customer Y");
callCenter.dispatchCall(call4); // Alice handles the call again
}
}
Call Class
caller
andhandler
fields : set asprivate
to ensure encapsulationIt prevents
direct access
to this fields (call.caller -> forbidden)By providing indirect access via
methods
(getCaller, getHandler and setHandler), offers theData Protection
andValidation
1 2 3 4 5 6 7
public void setHandler(Employee handler) { if (handler == null) { throw new IllegalArgumentException("Handler cannot be null"); } this.handler = handler; }
return;
is used tostop
the execution of the functionUsually used in
void
functions
Employee
this
1 2 3 4 5
public void handleCall(Call call) { this.isFree = false; call.setHandler(this); ... }
call.setHandler(this)
value : assinged the employeePrint line
1 2
System.out.println(this.rank.substring(0, 1).toUpperCase() + this.rank.substring(1) + " " + this.name + " is handling the call from " + call.getCaller() + ".");
this.rank.substring(0,1).toUpperCase() -> Change the first character to uppercase (“respondent” -> “R”)
this.rank.substring(1) -> print word without the first character (“respondent” -> “espondent”)
super
super(name, "respondent")
calls the parent class(Employee) constructor(Employee(String name, String rank))and initialize the Employee class fields (name and rank)
CallCenter
addEmplyee
Methodemployee instanceof Responent
checks if the employee(object) is an instance of theRespondent
class or subclassIf it is true, the
employee
is cast to theRespondent
type. Because onlyRespondent
(objects) are added to the dequeWhy cast?
respondents
deque is typed asDeque<Respondent>
. Only objects of type(Respondent) can addedpublic void dispatchCall(Call call)
Methodfor (Deque<? extends Employee> queue : new Deque[]{respondents, managers, directors})
Loops (respondents, managers, directors) and assign to the
queue
(variable) one by one in each iterationfor (Employee employee : queue)
Example.
respondents
during the first iteration of the loop, each employee in the queue is assigned to theemployee
(variable)