首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >呼叫中心升级摘录,使用责任链模式

呼叫中心升级摘录,使用责任链模式
EN

Code Review用户
提问于 2018-08-28 20:11:53
回答 1查看 246关注 0票数 5

这是我在网上发现的一次编码面试,要在30分钟内解决:

为应用程序设计一个面向对象的概念,如果员工不能解决问题,员工可以根据他们的资历级别发送他们的来电。

我选择了责任链模式,我也使用了Null模式。请回顾OOP原则和具体的设计模式的实现。

单元测试只是一个代码示例。

代码语言:javascript
复制
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace DesignPatternsQuestions
{
    [TestClass]
    public class ChainOfResponsibilityTest
    {
        [TestMethod]
        public void PhoneCallDispatchCORTest()
        {
            PhoneCallHandler gilad = new PhoneCallHandler(new LowLevel("Gilad"));
            PhoneCallHandler bonno = new PhoneCallHandler(new LowLevel("Bonno"));
            PhoneCallHandler batel = new PhoneCallHandler(new MediumLevel("Batel"));
            PhoneCallHandler daniel = new PhoneCallHandler(new HighLevel("Daniel"));
            gilad.RegisterNext(batel);
            bonno.RegisterNext(batel);
            batel.RegisterNext(daniel);

            BankPhoneCall call1 = new BankPhoneCall(1500);
            bool res = gilad.GetPhoneCall(call1);
            Assert.IsTrue(res);
        }
    }

    public interface IPhoneCall
    {
        int Budget { get; set; }
    }

    public class BankPhoneCall :IPhoneCall
    {

        public BankPhoneCall(int budget)
        {
            Budget = budget;
        }

        public int Budget { get; set; }
    }

    public interface IPhoneCallHandler
    {
        bool GetPhoneCall(IPhoneCall phoneCall);
        //the same item is able to call next Item in the chain of command
        void RegisterNext(IPhoneCallHandler employee);
    }

    public class PhoneCallHandler : IPhoneCallHandler
    {
        private IPhoneCallHandler _nextCallHandler = EndOfChainHandler.Instance;
        private Employee _employee;

        public PhoneCallHandler(Employee employee)
        {
            _employee = employee;
        }
        public bool GetPhoneCall(IPhoneCall phoneCall)
        {
            bool res = _employee.Resolve(phoneCall);
            if (!res)
            {
                //handle _nextcallHandler == null with null pattern
                return _nextCallHandler.GetPhoneCall(phoneCall);
            }
            return res;
        }

        public void RegisterNext(IPhoneCallHandler nextCallHandler)
        {
            _nextCallHandler = nextCallHandler;
        }
    }


    /// <summary>
    /// null pattern
    /// </summary>
    public sealed class EndOfChainHandler : IPhoneCallHandler
    {
        private static readonly Lazy<EndOfChainHandler> lazy = new Lazy<EndOfChainHandler>(()=> new EndOfChainHandler());
        public static EndOfChainHandler Instance { get { return lazy.Value; } }
        public bool GetPhoneCall(IPhoneCall phoneCall)
        {
            return false;
        }

        public void RegisterNext(IPhoneCallHandler employee)
        {
            throw  new InvalidOperationException("can't register next to null");
        }
    }

    public abstract class Employee
    {
        protected int _maxBudget;

        public string Name { get;set; }
        public Employee(string name, int maxBudget)
        {
            _maxBudget = maxBudget;
            Name = name;
        }

        public bool Resolve(IPhoneCall phoneCall)
        {
            return phoneCall.Budget <= _maxBudget;
        }
    }
    public class LowLevel : Employee
    {
        public LowLevel(string name)
            : base(name, 1000)
        {
        }
    }

    public class MediumLevel : Employee
    {
        public MediumLevel(string name)
            : base(name, 5000)
        {
        }
    }

    public class HighLevel : Employee
    {
        public HighLevel(string name)
            : base(name, 10000)
        {
        }
    }
}
EN

回答 1

Code Review用户

回答已采纳

发布于 2019-09-04 16:42:52

评论

做得好,在这个实现中我不会做什么改变。我会授予你卑微的徽章,因为你把自己当成了LowLevel的雇员:)

延迟和空模式实现得很好(除了可能引入空->的小问题外,请参阅次要问题)。责任链看上去是在所难免的。您甚至在处理程序和员工之间使用了访问者模式。每个特定的员工都会产生不同的处理电话的行为。

次要问题

  • 在我看来,IPhoneCall作为接口似乎太过分了。这只是一只波科。
  • 在公共入口点(如public PhoneCallHandler(Employee employee) )中检查针对null的参数。
  • GetPhoneCall可以写得更紧凑:return _employee.Resolve(phoneCall) || _nextCallHandler.GetPhoneCall(phoneCall);
  • RegisterNext不应该允许null,因为这绕过了您的EndOfChainHandler.Instance模式以避免null处理。
票数 6
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

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

复制
相关文章

相似问题

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