首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >呼叫中心设计

呼叫中心设计
EN

Code Review用户
提问于 2016-06-09 04:26:12
回答 1查看 2.2K关注 0票数 1

假设您有一个呼叫中心,有三个级别的员工:被访者、经理和主管。来电必须首先分配给免费的应答者。如果应答者不能处理电话,他或她必须将电话升级到经理那里。如果经理没有自由或无法处理,那么电话应该升级到主管。针对这个问题设计类和数据结构。实现一个方法dispatchCall(),它为第一个可用的雇员分配一个调用。

代码语言:javascript
复制
package design;

import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;

public class CallCenter {
    Employee[] employees;
    int size = 100;
    Map<Employee,PhoneCall> callMap = new TreeMap<Employee, PhoneCall>(new Comparator<Employee>() {
        @Override
        public int compare(Employee o1, Employee o2) {
            return 0;
        }
    });
    Queue<PhoneCall> calls ;
    PriorityQueue<Employee> dispatchQueue;
    CallCenter(){
      employees = new Employee[size];
      calls = new LinkedBlockingQueue<PhoneCall>();
      dispatchQueue = new PriorityQueue<Employee>(new Comparator<Employee>() {
          @Override
          public int compare(Employee o1, Employee o2) {
              if(o1.id > o2.id) return -1;
              else if(o1.id < o2.id) return 1;
              else return 0;
          }
      });
        for(int i = 0;i<size;i++){
            if(i==0 || i==1){
                employees[i] = new Director(i);
            }
            else if(i>=2 && i<=6){
                employees[i] = new Manager(i);
            }else{
                employees[i] = new Respondent(i);
            }
            dispatchQueue.offer(employees[i]);
        }
    }

    public void dispatchCall(PhoneCall p){
        if(dispatchQueue.isEmpty()){
            calls.offer(p);
        }else{
            callMap.put(dispatchQueue.poll(), p);
        }
    }

    public void endCall(Employee emp){
        if(callMap.containsKey(emp)){
            callMap.remove(emp);
            dispatchQueue.offer(emp);
        }
    }


    public void processCallsQueue(){
        while(!calls.isEmpty()){
            if(dispatchQueue.isEmpty())break;
            else dispatchCall(calls.poll());
        }
    }

    public  Employee getRandomEmployee(){
        Random rn = new Random();
        int randomPosition = rn.nextInt(100);
        return employees[randomPosition];

    }



}

class PhoneCall{
    int id;
    String location;
    String number;

    PhoneCall(){
        Random rand = new Random();
        id = rand.nextInt();
        location = "US";
        number = new BigInteger(130,rand).toString();
    }
}

class Employee{
    int id;
    String designation;
    int priority; //priority is the call priority 1. Respondent, 2. Manager , 3. Director

    Employee(){

    }
    Employee(int id){
        this.id = id;
    }

}

class Manager extends Employee{

    Manager(int id){
        super(id);
        designation = "MANAGER";
        priority = 2;
    }
}

class Director extends Employee{

    Director(int id){
        super(id);
        designation = "DIRECTOR";
        priority = 3;
    }
}

class Respondent extends Employee{

    Respondent(int id){
        super(id);
        designation="RESPONDENT";
        priority=1;
    }
}

这个设计是不是太肤浅了,不能在面试中完成?任何对设计的反馈都将受到极大的赞赏。

EN

回答 1

Code Review用户

回答已采纳

发布于 2016-06-09 19:20:16

Employee[] employees; int size = 100;

数组是有效的,但不灵活。我认为您更喜欢像List这样的东西的灵活性。

还不清楚为什么size是100。

对象字段通常应该是private。其他作用域可能是有效的,但是您应该有使用它们的特定原因。应该在某个地方发表评论。

public int compare(Employee o1, Employee o2) { return 0; }

如果您不关心订单,为什么要使用TreeMap

如果你在做一些聪明的事情,请在代码中写一个注释,解释为什么你想让每个员工都平等。

您有两个匿名定义的Comparator<Employee>对象。如果有一个名为类的类,则只需传递该类的对象即可。不需要每次都重新定义compare方法。

} else if(i>=2 && i<=6){ employees[i] = new Manager(i); }else{

}else使用两种不同的样式。请选一个。我更喜欢同一行的} else,但两者的一致性要比混合多种样式更好。

public void dispatchCall(PhoneCall p){ if(dispatchQueue.isEmpty()){ calls.offer(p); }else{ callMap.put(dispatchQueue.poll(), p); } }

问题描述说

实现一个方法dispatchCall(),它为第一个可用的雇员分配一个调用。

但这种方法不能做到这一点。如果有可用的话,它会向员工发送一个电话。或者,如果没有,则将调用放在队列中。

我的解读是,dispatchCall应该阻塞,直到员工可用为止。

if(callMap.containsKey(emp)){ callMap.remove(emp); dispatchQueue.offer(emp); }

考虑到remove的工作方式,您只需说:

代码语言:javascript
复制
        if (callMap.remove(emp) != null) {
            dispatchQueue.offer(emp);
        }

目前还不清楚编译器是否会将两者优化为相同的字节代码。

while(!calls.isEmpty()){ if(dispatchQueue.isEmpty())break; else dispatchCall(calls.poll()); }

我会觉得这更容易理解为

代码语言:javascript
复制
        while (!calls.isEmpty() && !dispatchQueue.isEmpty()) {
            dispatchCall(calls.poll());
        }

在我遵循之前的逻辑之前,我做了几次解读。

public Employee getRandomEmployee(){

你从来没有用过这种方法。

Random rn = new Random();

与其在每个方法调用中创建一个新的Random对象,不如为整个程序创建一个对象。可能作为static字段出现在CallCenter上。

如果应答者不能处理电话,他或她必须将电话升级到经理那里。如果经理没有自由或无法处理,那么电话应该升级到主管。

您完全依赖于id命令来完成此操作。那么,如果你增加了一个新导演,会发生什么呢?您必须为经理和答卷者重新分配id值。如果你提拔别人也是一样的。

更糟糕的是,你没有记录这种行为。因此,如果评估代码的人没有意识到这一点,他们就会在这个需求上让你失望。

String designation;

与其让designation成为String,不如让它成为一个enum更有意义。字符串中的错误是一个运行时问题。enum中的错误将在编译时捕获。

int priority; //priority is the call priority 1. Respondent, 2. Manager , 3. Director

这只保留了另一种形式的designation。你设定,但从来不使用其中任何一个。为什么有他们?

评价

如果我在这个问题上对你进行评估的话,我会给你打个记号,因为你没有遵守指示。我不一定觉得它太肤浅,也没有足够的专注。您将额外的精力用于创建不必要的字段,例如PhoneCall中的所有字段。但实际上你并没有实现这些基础。

这段代码似乎实现了一半。就像你有一堆想法,你开始了,但没有完成。代码应该是有目的的。如果你决定不使用某物,那就把它移除,而不是半途而废。

你也不做任何测试。我不清楚如何运行这段代码。要真正评估它,我必须从头开始编写我自己的测试。编写您自己的测试不仅会使我更容易测试,还会使您更有可能在发送代码之前捕获错误。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/131496

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档