如果訂單處理程序都包含在一個類,並只用在那裏,你可以簡單地這樣做以下,延長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