java - 面向对象设计 : Giving too much responsibility to a value object

标签 java oop

我在 Cracking the Coding Interview 一书中遇到了这个设计问题:

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().

书上的解答

public class CallHandler {
    static final int LEVELS = 3; // we have 3 levels of employees
    static final int NUM_FRESHERS = 5; // we have 5 freshers
    ArrayList<Employee>[] employeeLevels = new ArrayList[LEVELS];
    // queues for each call’s rank
    Queue<Call>[] callQueues = new LinkedList[LEVELS];

    public CallHandler() { ... }

    Employee getCallHandler(Call call) {
        for (int level = call.rank; level < LEVELS - 1; level++) {
            ArrayList<Employee> employeeLevel = employeeLevels[level];
            for (Employee emp : employeeLevel) {
                if (emp.free) {
                    return emp;
                }
            }
        }
        return null;
    }

    // routes the call to an available employee, or adds to a queue
    void dispatchCall(Call call) {
        // try to route the call to an employee with minimal rank
        Employee emp = getCallHandler(call);
        if (emp != null) {
            emp.ReceiveCall(call);
        } else {
            // place the call into queue according to its rank
            callQueues[call.rank].add(call);
        }
    }
    void getNextCall(Employee e) {...} // look for call for e’s rank
}

class Call {
    int rank = 0; // minimal rank of employee who can handle this call
    public void reply(String message) { ... }
    public void disconnect() { ... }
}

class Employee {
    CallHandler callHandler;
    int rank; // 0- fresher, 1 - technical lead, 2 - product manager
    boolean free;
    Employee(int rank) { this.rank = rank; }
    void ReceiveCall(Call call) { ... }
    void CallHandled(Call call) { ... } // call is complete
    void CannotHandle(Call call) { // escalate call
        call.rank = rank + 1;
        callHandler.dispatchCall(call);
        free = true;
        callHandler.getNextCall(this); // look for waiting call
    }
}

class Fresher extends Employee {
    public Fresher() { super(0); }
}
class TechLead extends Employee {
    public TechLead() { super(1); }
}
class ProductManager extends Employee {
    public ProductManager() { super(2); }
}

这个解决方案不是很令人满意,主要是因为它涉及将 CallHandler 对象传递给 Employee。我认为 Employee 应该被视为一个值对象,这意味着它的工作应该主要是保存数据而不知道包含真正业务逻辑的实体(如 CallHandler)。所以我很想知道有什么更好的方法来设计这个。我有 ActionScript 背景,因此我可能会使用 ActionScript 的事件模型从 Employee 发送消息并在 CallHandler 中收听它们。

最佳答案

有无数种方法可以设计这个系统(这就是让开发软件如此有趣的原因),有些方法比其他方法更好。提供的答案不是最好的,但它有效。

您必须有某种方式让员工通过对 Callhandler 进行某种回调来升级调用。无论是通过传递 Callhandler 还是让 Employeecallhandler 监听事件来完成,都是好主意。给定的解决方案更简单,因此更容易为目标受众所理解。基于事件的解决方案更复杂,更难编写,但可扩展性更强且更易于修改。

例如,如果您必须为某种“监督者”添加一项新功能来监控员工成功解决调用的频率与他们升级的次数相比,编写一个新的事件监听器比尝试鞋拔一个介于 Employee 和 Callhandler 之间的新对象。

基本上,是的,您的想法可能比解决方案更好,但它们都回答了问题。

关于java - 面向对象设计 : Giving too much responsibility to a value object,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18623180/

相关文章:

c++ - 具有不同构造函数参数的 CPP 对象数组

php - 接口(interface)的现实世界实现

java - size() 在 java 的 ArrayList 类中如何工作?

java - <xdr :absoluteAnchor> shape moves with DOCX4J in excel

java - 尝试保存 Iterable 时执行独立工作时出错

ios - 无法调用 UIWebView 上的所有功能

oop - 不同模块中抽象类型的扩展

java - 如何重构以下代码

java - 如何使用 iText 查找文本并将其替换为 pdf 文件

java - 当只有按钮对象具有 .addActionListener 时,为什么此代码中的 JFrame 会对 ActionEvents 使用react?