当前位置:  开发笔记 > 编程语言 > 正文

面向对象的设计:对值对象赋予过多的责任

如何解决《面向对象的设计:对值对象赋予过多的责任》经验,为你挑选了1个好方法。

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

想象一下,您拥有一个拥有三级员工的呼叫中心:更新,技术主管(TL),产品经理(PM).可以有多个员工,但只有一个TL或PM.拨打电话必须分配给免费的新手.如果新手无法接听电话,他或她必须将电话升级为技术负责人.如果TL没有空闲或无法处理,那么呼叫应该升级为PM.设计此问题的类和数据结构.实现方法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[] employeeLevels = new ArrayList[LEVELS];
    // queues for each call’s rank
    Queue[] callQueues = new LinkedList[LEVELS];

    public CallHandler() { ... }

    Employee getCallHandler(Call call) {
        for (int level = call.rank; level < LEVELS - 1; level++) {
            ArrayList 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.



1> dkatzel..:

设计这个系统有很多方法(这就是使开发软件如此有趣的原因)某些方法比其他方法更好.提供的答案不是最好的,但它有效.

你必须有一些员工的方式通过做一些回调来升级一个电话Callhandler.无论是通过绕过Callhandler或有Employees和callhandler听取事件来完成都是好主意.给定的解决方案更简单,因此更容易理解目标受众.基于事件的解决方案更复杂,更难编写,但更具可扩展性且更易于修改.

例如,如果您必须为某种"监督者"添加新功能,以监控员工成功解决呼叫的频率与他们升级的次数,那么只需编写新的事件监听器就可以轻松编写. Employee和Callhandler之间的新对象.

基本上,是的,你的想法可能比解决方案更好,但他们都回答了这个问题.

推荐阅读
360691894_8a5c48
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有