2

Cracking the Coding Interview という本の中で、この設計上の質問に出くわしました。

新卒、テクニカル リード (TL)、プロダクト マネージャー (PM) の 3 つのレベルの従業員がいるコール センターがあるとします。複数の従業員を配置できますが、TL または PM は 1 人だけです。電話の着信は、空いている新入社員に割り当てる必要があります。初任者が電話に対応できない場合は、テクニカル リードに電話をエスカレートする必要があります。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<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このソリューションは、主に にオブジェクトを渡す必要があるため、あまり満足のいくものではありませんEmployeeEmployee値オブジェクトとして扱われるべきだと思います。つまり、実際のビジネス ロジックを含むエンティティ (のようなCallHandler) を意識せずに、ほとんどの場合データを保持する必要があります。ですから、これを設計するためのより良い方法を見つけることに興味があります。私は ActionScript のバックグラウンドを持っているので、おそらく ActionScript のイベント モデルを使用して からメッセージを送信Employeeし、CallHandler.

4

2 に答える 2

6

このシステムを設計する方法は無数にあります (それがソフトウェア開発をとても楽しいものにしています) いくつかの方法は他の方法よりも優れています. 提供された回答は最善ではありませんが、機能します。

何らかの方法で Employee にコールバックを実行してコールをエスカレートする必要がありますCallhandler。を渡すか、 とCallhandlerEmployeeイベントcallhandlerをリッスンさせるかは、どちらも良い考えです。与えられた解決策はより単純であるため、対象となる聴衆にとってより理解しやすいものです。イベント ベースのソリューションは、より複雑で記述が難しくなりますが、スケーラブルで変更が容易です。

たとえば、従業員が通話を正常に解決する頻度とエスカレートする回数を監視するために、ある種の「監督者」に新しい機能を追加する必要がある場合、新しいイベント リスナーを作成するだけで簡単に解決できます。 Employee と Callhandler の間の新しいオブジェクト。

基本的に、はい、あなたのアイデアはおそらく解決策よりも優れていますが、どちらも質問に答えています.

于 2013-09-04T20:45:57.453 に答える