patterncsharpModerate
Review of object oriented design for a sample interview question
Viewed 0 times
sampledesigninterviewfororientedobjectquestionreview
Problem
I'm going over the interview questions from "Cracking the Coding Interview" and one of the chapters (Chapter 7) deals with Object Oriented Design (OOD). The requirements for one of the problems are as follows:
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
escalate the call to technical lead.
If the TL is not free or not able to
handle it, then the call should be
escalated to PM. Design the classes
and data structures for this problem.
Implement a method getCallHandler().
I've written a solution in C#, it was not compiled (suggested by the author of the book) and it is currently not multithreaded. My solution is a bit long, but it should be really simple to understand.
Based on my understanding of the problem, I've established a "chain of command" where each employee knows who his/her superior is. Calls get handled in the following manner:
NOTE: multithreading will be added in a later revision, so please ignore any multithreading issues.
```
enum EStatus{ HANDLING, ESCALATED, QUEUED }
enum ERank{ FRESHER, TECH_LEAD, PROD_MANAGER }
abstract class Employee
{
public ERank Rank{get; private set;}
public Employee(ERank rank)
{
Rank = rank;
}
public abstract EStatus ServiceCall(Call call);
}
class Fresher:Emp
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
escalate the call to technical lead.
If the TL is not free or not able to
handle it, then the call should be
escalated to PM. Design the classes
and data structures for this problem.
Implement a method getCallHandler().
I've written a solution in C#, it was not compiled (suggested by the author of the book) and it is currently not multithreaded. My solution is a bit long, but it should be really simple to understand.
Based on my understanding of the problem, I've established a "chain of command" where each employee knows who his/her superior is. Calls get handled in the following manner:
- If a fresher is given a call which he/she cannot handle, then the fresher escalates the call to his/her superior: a tech lead.
- If there are no free freshers, then the tech lead automatically gets the call.
- If the tech lead is busy or cannot service the call, then he/she escalates the call to the product manager.
- If the product manager (PM) is busy, then the call gets queued on the PM's queue and dequeued once their current call is serviced.
NOTE: multithreading will be added in a later revision, so please ignore any multithreading issues.
```
enum EStatus{ HANDLING, ESCALATED, QUEUED }
enum ERank{ FRESHER, TECH_LEAD, PROD_MANAGER }
abstract class Employee
{
public ERank Rank{get; private set;}
public Employee(ERank rank)
{
Rank = rank;
}
public abstract EStatus ServiceCall(Call call);
}
class Fresher:Emp
Solution
In short, in my opinion, I think you've done too much.
It seems like your design has gone beyond a design for the initial interview question and into an exercise of your own.
However, I don't have the book you're reading, so you may be going off more than just that snippet in your question.
Based on the principle:
Do the simplest thing that could
possibly work.
The basics I pulled from that question were:
i.e. I think the question is just after an implementation of
I came up with the following:
That would be the starting point based on what the question says. After this would usually be a period of interaction between interviewee and interviewer(s) in which assumptions could be addressed and the design discussed/updated with more detail, such as employees being in a busy state etc.
I think your design is a step beyond that.
The combination of class and enumeration for the different employee types is something we both went for. However, I chose an interface over a base class. I don't think your base class provides a lot of value - just code to assign a
One point for further discussion might be where it states:
If a fresher can’t handle the call, he
or she must escalate the call to
technical lead.
This may suggest that they want a fresher object to communicate directly with their superior like in your design (as opposed to my implementation, where employees don't need to know each other even exist - similar to many workplaces!). This could be clarified in the interview. However, I prefer my design because of the looser coupling between employees.
As far as multithreading goes, I'd expect quite a bit of discussion on
before it got added to any code. But like I say, it does seem like your design is more than just an answer to the interview question.
It seems like your design has gone beyond a design for the initial interview question and into an exercise of your own.
However, I don't have the book you're reading, so you may be going off more than just that snippet in your question.
Based on the principle:
Do the simplest thing that could
possibly work.
The basics I pulled from that question were:
- We need a way to represent the three different kinds of employees.
- We need a way of representing a call.
- We need a way of choosing an employee to handle a call (the getCallHandler method).
i.e. I think the question is just after an implementation of
GetCallHandler and some basic definitions of the types involved.I came up with the following:
public class Call
{
// TODO: Implement Call.
}
public enum EmployeePosition
{
Fresher,
TechnicalLead,
ProductManager
}
public class CallCentre
{
private IList employees;
public IEmployee GetCallHandler(Call call)
{
return employees.Where(e => e.CanHandle(call))
.OrderBy(e => e.Position)
.FirstOrDefault();
}
public CallCentre(IList employees)
{
if (employees == null)
{
throw new ArgumentNullException("employees");
}
this.employees = employees;
}
}
public interface IEmployee
{
EmployeePosition Position { get; }
Boolean CanHandle(Call call);
}
public class Fresher : IEmployee
{
public EmployeePosition Position { get { return EmployeePosition.Fresher; } }
public Boolean CanHandle(Call call)
{
// TODO: Logic for handling a call.
}
}
// Similar implementations of IEmployee for TechnicalLead and ProductManager.That would be the starting point based on what the question says. After this would usually be a period of interaction between interviewee and interviewer(s) in which assumptions could be addressed and the design discussed/updated with more detail, such as employees being in a busy state etc.
I think your design is a step beyond that.
The combination of class and enumeration for the different employee types is something we both went for. However, I chose an interface over a base class. I don't think your base class provides a lot of value - just code to assign a
Rank property. My proposal has the benefit that someone's not going to break implementation for some employees inadvertantly by altering the base class. The interface contains no implmentation. Using an interface also allows the employee classes to use a different base class in the future if needs be.One point for further discussion might be where it states:
If a fresher can’t handle the call, he
or she must escalate the call to
technical lead.
This may suggest that they want a fresher object to communicate directly with their superior like in your design (as opposed to my implementation, where employees don't need to know each other even exist - similar to many workplaces!). This could be clarified in the interview. However, I prefer my design because of the looser coupling between employees.
As far as multithreading goes, I'd expect quite a bit of discussion on
- how it might be implemented
- potential issues with different threading models
- potential bottlenecks
- typical call volume
before it got added to any code. But like I say, it does seem like your design is more than just an answer to the interview question.
Code Snippets
public class Call
{
// TODO: Implement Call.
}
public enum EmployeePosition
{
Fresher,
TechnicalLead,
ProductManager
}
public class CallCentre
{
private IList<IEmployee> employees;
public IEmployee GetCallHandler(Call call)
{
return employees.Where(e => e.CanHandle(call))
.OrderBy(e => e.Position)
.FirstOrDefault();
}
public CallCentre(IList<IEmployee> employees)
{
if (employees == null)
{
throw new ArgumentNullException("employees");
}
this.employees = employees;
}
}
public interface IEmployee
{
EmployeePosition Position { get; }
Boolean CanHandle(Call call);
}
public class Fresher : IEmployee
{
public EmployeePosition Position { get { return EmployeePosition.Fresher; } }
public Boolean CanHandle(Call call)
{
// TODO: Logic for handling a call.
}
}
// Similar implementations of IEmployee for TechnicalLead and ProductManager.Context
StackExchange Code Review Q#720, answer score: 11
Revisions (0)
No revisions yet.