在不使用switch语句的情况下在C#中路由对象

时间:2014-06-17 15:41:28

标签: c# .net object conditional-statements object-oriented-analysis

我正在c#.net 4.0中编写一个软件,并且在确保代码库在特定区域中可扩展,可重用和灵活的情况下遇到了问题。

我们有数据需要在离散的组织单位中细分。随着公司的发展,这些单位需要进行更改,分类,删除和添加。

无论我们如何对数据结构进行切片,我们都会遇到一系列条件语句(大约100个左右开始),我们正试图避免这种情况,允许我们轻松修改OU。

我们希望找到一种面向对象的方法,它允许我们根据该对象的属性将对象路由到不同的工作流,而不必每次都添加switch语句。

所以,例如,假设我有一个名为“Order”的对象进入系统。该对象内部有'orderItems'。这些不同类型的'orderItems'中的每一个都需要在代码中触发不同的函数以便适当地处理。每个'orderItem'都有不同的工作流程。条件看起来基本上就像这样 -

if(order.orderitem == 'photo')
  {do this} 
else if(order.orderitem == 'canvas')
  {do this}

编辑:试图澄清。

4 个答案:

答案 0 :(得分:0)

我不确定你的问题是否定义得很清楚,你需要更多细节 - 样本数据,示例代码,你尝试了什么......

  

无论我们如何分割数据结构,我们都会遇到一系列条件语句(大约100个左右开始)我们正在努力避免

这通常意味着您尝试对代码中的数据进行编码 - 只需添加一个数据字段(或少数几个)。

有可能你的if相互关联,很难提出100个独立的ifs - 这意味着你有100个独立的分支来处理100个独立的数据条件。在我的职业生涯中,我还没有遇到过这样的问题,真的需要硬编码100 ifs。

最糟糕的情况是,您可以使附加数据字段包含配置文件,甚至包含您选择的脚本。无论哪种情况 - 如果您需要100个ifs

,您的数据都是不完整的

通过更新,您在这里提出了一个简单的简单方法,一种低技术。你可以通过依赖注入和一些配置做得更好,但也可能过度,所以要小心:

public class OrderHandler{ 
  public static Dictionary<string,OrderHandler> Handlers = new Dictionary<string,OrderHandler>(){
  {"photo", new PhotoHandler()},
  {"canvas", new CanvasHandler()},
};

  public virtual void Handle(Order order){
    var handler = handlers[order.OrderType];
    handler.Handle(order);
  } 
}

public class PhotoHandler: OrderHandler{...}
public class CanvasHandler: OrderHandler{...}

答案 1 :(得分:0)

您可以做的是 - &#34;基于消息的路由&#34;或者&#34;基于消息内容&#34;路由 - 取决于您如何实现它。

简而言之,您应该实现组织单位以查找他们感兴趣的消息,而不是在业务逻辑中使用条件语句。

例如: 假设您的组织有以下部门 - &#34; Plant Products&#34;,&#34; Paper Products&#34;,&#34; Utilities&#34;。假设订单中只有一个地方 - 订购(模块)。
这是一个传入消息的示例。

Party:"ABC Cop"
Department: "Plant Product"
Qty: 50
Product: "Some plan"

发布包含此信息的邮件。在处理&#34; Plant Products&#34;的订单的模块中。配置它以便它监听具有&#34; Department = Plant Products&#34;的消息。这样,您就可以在部门模块上而不是在主要订购模块上推卸责任。

您可以使用NServiceBus,BizTalk或您可能已有的任何其他ESB来执行此操作。

This是如何在BizTalk中完成的,this是如何在NServiceBus中做的

答案 2 :(得分:0)

采用具体示例: 你可以让一些评估员接受订单并迭代每个订单项。而不是处理如果逻辑引发事件参数中的事件参数照片,画布细节。

拥有一系列对象&#39;发起人&#39;定义:1)一个可以处理Evaluator消息的处理程序,2)一个简单的bool,可以设置为指示他们是否知道如何处理消息中的某些内容,以及3)一个Action或Process方法,它可以执行或启动流程。设计一个接口来抽象这些。

发出消息。访问每个Initiator,询问它是否可以处理lineItem,如果它可以告诉它这样做。处理工作由“发起人”启动。他们可以打电话给其他工作流程等。

将上面列出的部分命名为最适合您的域名。这应该提供一些灵活性。根据并发处理要求和启动器之间的工作流程依赖性,可能会出现问题。

一般,在不了解更多细节,项目规模,工作流程,用例等情况下,很难发表评论。

答案 3 :(得分:0)

您是否考虑过键入OrderItem

public class PhotoOrderItem : OrderItem {}
public class CanvasOrderItem : OrderItem {}

另一种选择是使用策略模式。在OrderItem的{​​{1}}类定义中添加额外的属性,并使用OrderProcessStrategy / PhotoOrderStrategy包含所有不同的逻辑。

CanvasOrderStrategy