OOP Problem from Cracking the Code Interview
17 Dec 2014This is a practice problem to think about object oriented design. I wasn’t sure how far to go wtih the solution. I have a basic working solution and an example. Feel free to solve and compare, or simply discuss.
Question
Imagine you have a call center with three levels of employees: fresher , technical lead (TL), product manager (PM). There can be multiple employees, but only one TL or PM. An incoming telephone call must be allocated to a fresher who is free. If a fresher can’t handle the call, he or she must handle it, then the call should be escalated to PM. Design the classes and data structures for this problem. Implement a method getCallHandler().
My Solution
class CallHandler
attr_reader :product_manager, :tech_lead, :freshers, :calls
def initialize(args={})
@product_manager = args[:product_manager]
@tech_lead = args[:tech_lead]
@freshers = args[:freshers]
@calls = []
end
def get_call_handler
employees_by_rank.find { |emp| emp.free? }
end
def employees_by_rank
[freshers.shuffle, tech_lead, product_manager].flatten
end
def route_incoming(call)
employee = get_call_handler
if employee
employee.take(call)
else
calls << call
end
end
def display_status
puts "CALL STATUS\n----------"
employees_by_rank.each_with_index do |emp,i|
printf("%d. %15s: %5s: %s\n", i+1, emp.title, emp.name, emp.status)
end
puts
end
end
class Employee
attr_reader :name, :title
attr_accessor :status
def initialize(name, title)
@name = name
@title = title
@status = :free
end
def take(call)
self.status = :busy
call.employee = self
call.status = :on_phone
end
def end(call)
self.status = :free
call.status = :answered
end
def free?
status == :free
end
end
class Call
attr_accessor :employee, :status
def initialize(name, message)
@caller = name
@message = message
@status = :on_hold
end
end
An Example
employee1 = Employee.new('John', 'Product Manager')
employee2 = Employee.new('Jim', 'Tech Lead')
employee3 = Employee.new('James', 'Fresher')
employee4 = Employee.new('Joe', 'Fresher')
call_center = CallHandler.new(
product_manager: employee1,
tech_lead: employee2,
freshers: [employee3, employee4] )
call1 = Call.new("Mr T", "My WoW account isn't working.")
call2 = Call.new("Mr Kim", "Issue with login...")
call_center.route_incoming(call1)
call_center.route_incoming(call2)
call_center.display_status
employee3.end(call1)
call_center.display_status
Output
CALL STATUS
----------
1. Fresher: James: busy
2. Fresher: Joe: busy
3. Tech Lead: Jim: free
4. Product Manager: John: free
CALL STATUS
----------
1. Fresher: Joe: busy
2. Fresher: James: free
3. Tech Lead: Jim: free
4. Product Manager: John: free