Design (LLD) Call Center  - Machine Coding

Design (LLD) Call Center - Machine Coding

Play this article

Table of contents

No heading

No headings in the article.

Features Required:

  1. Different types of companies:

    • Companies can have different structures (e.g., inbound, outbound, blended).
  2. Registration Fee:

    • Different companies might have different registration fees.
  3. Liability:

    • Track and manage liability aspects for each company.
  4. Minimum Directors:

    • Ensure compliance with regulations regarding the minimum number of directors.
  5. User Management:

    • Manage users with different roles (e.g., agents, supervisors, administrators).
  6. Call Handling:

    • Handle incoming and outgoing calls efficiently.
  7. Reporting and Analytics:

    • Provide insights into call center performance.

Design Patterns Involved or Used:

  1. Factory Method Pattern:

    • Use the Factory Method Pattern to create instances of different types of companies.
  2. Observer Pattern:

    • Implement the Observer Pattern for notifying users and systems about changes in call center status or events.
  3. Command Pattern:

    • Use the Command Pattern for managing user commands related to call handling.
  4. Composite Pattern:

    • Organize users and roles using the Composite Pattern, allowing hierarchical structures.
  5. State Pattern:

    • Apply the State Pattern for managing the state of calls (e.g., ringing, ongoing, completed).

Code:

Below is a simplified Java-based code outline for some of the components mentioned. This is a basic representation; a complete system would require more classes and methods.

import java.util.ArrayList;
import java.util.List;

// Factory Method Pattern
interface CompanyFactory {
  Company createCompany(String type);
}

class InboundCompanyFactory implements CompanyFactory {
  public Company createCompany(String type) {
    if ("inbound".equalsIgnoreCase(type)) {
      return new InboundCallCenter();
    }
    // Handle other types of companies
    return null;
  }
}

// Observer Pattern
interface CallCenterObserver {
  void update(String event);
}

class User implements CallCenterObserver {
  private String name;

  public User(String name) {
    this.name = name;
  }

  public void update(String event) {
    System.out.println("User " + name + " received event: " + event);
  }
}

// Command Pattern
interface CallCommand {
  void execute();
}

class AnswerCallCommand implements CallCommand {
  public void execute() {
    System.out.println("Call answered");
  }
}

// Composite Pattern
abstract class UserComponent {
  abstract void displayInfo();
}

class UserLeaf extends UserComponent {
  private String name;

  public UserLeaf(String name) {
    this.name = name;
  }

  void displayInfo() {
    System.out.println("User: " + name);
  }
}

class UserComposite extends UserComponent {
  private List < UserComponent > users = new ArrayList < > ();

  public void add(UserComponent user) {
    users.add(user);
  }

  public void remove(UserComponent user) {
    users.remove(user);
  }

  void displayInfo() {
    for (UserComponent user: users) {
      user.displayInfo();
    }
  }
}

// State Pattern
interface CallState {
  void handleCall();
}

class RingingState implements CallState {
  public void handleCall() {
    System.out.println("Ringing state - waiting for user response");
  }
}

// Context class that uses State
class Call {
  private CallState state;

  public Call(CallState state) {
    this.state = state;
  }

  public void setState(CallState state) {
    this.state = state;
  }

  public void handleCall() {
    state.handleCall();
  }
}

// Concrete CallCenter class
class InboundCallCenter implements Company {
  private List < CallCenterObserver > observers = new ArrayList < > ();

  public void addObserver(CallCenterObserver observer) {
    observers.add(observer);
  }

  public void removeObserver(CallCenterObserver observer) {
    observers.remove(observer);
  }

  public void notifyObservers(String event) {
    for (CallCenterObserver observer: observers) {
      observer.update(event);
    }
  }
}

// Main class
public class CallCenterApp {
  public static void main(String[] args) {
    // Create a call center using Factory Pattern
    CompanyFactory companyFactory = new InboundCompanyFactory();
    Company callCenter = companyFactory.createCompany("inbound");

    // Observer Pattern
    CallCenterObserver user1 = new User("Alice");
    CallCenterObserver user2 = new User("Bob");

    ((InboundCallCenter) callCenter).addObserver(user1);
    ((InboundCallCenter) callCenter).addObserver(user2);

    ((InboundCallCenter) callCenter).notifyObservers("New call received");

    // Command Pattern
    CallCommand answerCommand = new AnswerCallCommand();
    answerCommand.execute();

    // Singleton Pattern
    LicenseManager licenseManager = LicenseManager.getInstance();
    if (licenseManager.checkLicense()) {
      System.out.println("License is valid");
    }

    // Composite Pattern
    UserComponent userLeaf1 = new UserLeaf("Charlie");
    UserComponent userLeaf2 = new UserLeaf("David");

    UserComponent userComposite = new UserComposite();
    ((UserComposite) userComposite).add(userLeaf1);
    ((UserComposite) userComposite).add(userLeaf2);

    userComposite.displayInfo();

    // State Pattern
    Call ringingCall = new Call(new RingingState());
    ringingCall.handleCall();
  }
}

In this example, I've expanded on the Factory, Observer, Command, Singleton, Composite, and State patterns. This is still a simplified version, and a real-world application would require more robust error handling, database integration, and additional features.

Did you find this article valuable?

Support Subhahu Jain by becoming a sponsor. Any amount is appreciated!