如果订单处理程序都包含在一个类,并只用在那里,你可以简单地这样做以下,延长Dictionary<int, Action>
当一个新的处理程序,方法的实现:
public class Foo
{
private readonly _handlerMap = new Dictionary<int, Action>
{
{ 1,() => handleOpenOrder() },
{ 2,() => handleShippedOrder() },
{ 3,() => handleCanceledOrder() }
}
public void TheMethodPreviouslyContainingTheSwitch(Order order)
{
var action = _handlerMap[order.OrderStatus.ID];
action.Invoke();
}
}
如果您在几个类中有switch-statement,我可能会为每个处理程序实现一个类并提取匹配的接口。如有必要,我可以详细说明。
编辑:
基于接口的方法,我脑子里想的,是基本相同的。这可能还不是一切问题的答案;-) 我写了这个从零开始(可能无法编译):
public interface IOrderHandler
{
int StatusId { get; }
void Handle(Order order);
}
public class OpenOrderHandler : IOrderHandler
{
public int StatusId => 1;
public void Handle(Order order)
{
// ...
}
}
public class OrderHandlerFactory
{
// this factory could be injected to all you dependant classes that need
// handlers to handle orders
private readonly _handlerMap = new Dictionary<int, Action>
{
// defining the IDs here and in the classes' defintions may be a bit
// redudant, but... meh ;)
{ 1,() => new OpenOrderHandler() },
{ 2,() => new ShippedOrderHandler() },
{ 3,() => new CancledOrderHandler() }
}
public IOrderHandler CreateHandlerByStatus(int orderStatusId)
{
// if the creation of a handler is expensive, it may be useful to
// only create a single handler that matches the orderStatusId
var action = _handlerMap[orderStatusId];
var handler = action.Invoke();
return handler;
}
public ICollection<IOrderHandler> CreateHandlers()
{
// it may be fine to create all handlers in each call of this method
// if the creation is inexpensive
return _handlerMap.Select(kvp => kvp.Value.Invoke()).ToList();
}
}
public class Foo
{
private readonly OrderHandlerFactory _orderHandlerFactory;
public Foo(OrderHandlerFactory orderHandlerFactory)
{
_orderHandlerFactory = orderHandlerFactory;
}
public void TheMethodPreviouslyContainingTheSwitch(Order order)
{
var handler = _orderHandlerFactory.CreateHandlerByStatus(order.OrderStatus.ID);
handler.Handle(order);
}
public void ThisMayBeUsefulIfMultipleHandlersRelateToAcertainStatus(Order order)
{
var handlers = _orderHandlerFactory.CreateHandlers();
handlers
.Where(handler => handler.StatusId == order.OrderStatus.ID)
.All(handler => handler.Handle(order));
}
}
是您的主要目的,避免了开关语句或自动化的具体订单处理程序的创建? – khlr
主要目标是避免switch语句,这样如果添加新的oder状态,我不必经过几个固定switch语句的类。 – narain
@narain给出这个描述,你的问题不是它是否是'switch'语句,而是你有完全相同的代码分散在几个类中,而不是在一个地方。无论是哪一个地方使用“开关”或其他机制,在任何情况下都不会产生任何影响。 – Servy