这是我在网上发现的一次编码面试,要在30分钟内解决:
为应用程序设计一个面向对象的概念,如果员工不能解决问题,员工可以根据他们的资历级别发送他们的来电。
我选择了责任链模式,我也使用了Null模式。请回顾OOP原则和具体的设计模式的实现。
单元测试只是一个代码示例。
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)
{
}
}
}发布于 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处理。https://codereview.stackexchange.com/questions/202690
复制相似问题