2013-01-06 44 views
0

我有這個主類接收一個queuemessage,然後使用其他幾個類來做一些工作。所有這些其他類自己使用一些較低類,最終數據被寫入數據庫或發送到wcf服務。異常和耦合

根據較低類別的結果,主類必須決定是否刪除queuemessage,或將其放在隊列中,或者將它發送到一個deadletterqueue。

例如,如果數據庫不可訪問,則可以將queuemessage放置在隊列中以稍後再試。但是,如果wdcf服務返回它不接受某些數據,則必須將該消息發送到deadletterqueue。

我有一對夫婦的方式來實現這樣的場景:

  1. 拋出異常,只有處理它們在主類。
  2. 拋出異常,但在每個調用類中捕獲它們。並重新拋出一個新的異常
  3. 返回結果的對象這表明錯誤/成功狀態

這是我對場景的想法:

  1. 如果最低的一個類拋出一個異常,而主要階級必須處理它,它將主要階級一直耦合到最低階級。如果其中一個最低類決定更改異常,則必須更改主類異常處理。

  2. 沒有什麼好方法讓上層類知道從C#中的被調用類拋出哪些異常。

  3. 這是我更喜歡的。每個被調用的方法都可以返回一個結果對象,一個枚舉指示成功或失敗,以及失敗類型。

所以,我的首選方法是選項3,但我不知道這是否在架構上可以接受。或者如果有更好的方法。

代碼

這是代碼(以簡化形式)看起來像:

QueueHandler

private static void HandleQueueMessage(Message message) 
{ 
    var deliveryOrder = deserialize(message.body); 

    var deliveryOrderHandler = new DeliveryOrderHandler(); 

    var result = deliveryOrderHandler.Execute(deliveryOrder.PubId); 

    switch (result) 
    { 
     case DeliveryOrderHandlerResult.DeliverySucceeded: 
      break; 

     case DeliveryOrderHandlerResult.FataleErrorInExternalSystem: 
     case DeliveryOrderHandlerResult.MAndatoryDocuhmentTransformationFailed: 
      SendDeliveryOrderToDeadletterQueue(deliveryOrder); 
      break; 

     default: 
      deliveryOrder.AbortCount = deliveryOrder.AbortCount + 1; 
      ResendDeliveryOrderToQueue(deliveryOrder); 
      break; 
    } 
} 

DeliveryOrderHandler

private DeliveryOrderHandlerResult Execute(long pubId) 
{ 
    DeliveryOrderHandlerResult deliveryOrderHandlerResult; 

    var transformationResult = GetTransformationResultaat(pubId); 

    if (transformationResult == TransformationResult.Success) 
    { 
     var deliveryResult = DeliverDocumentToExternalSystem(pubId); 

     if (deliveryResult.Status == DeliveryResult.Success) 
     { 
      SaveDeliveryResult(pubId, deliveryResult); 
     } 

     deliveryOrderHandlerResult = deliveryResult.Status; 
    } 
    else 
    { 
     switch (transformationResult) 
     { 
      case TransformationResult.NotStarted: 
       deliveryOrderHandlerResult = DeliveryOrderHandlerResult.TransformationNotStarted; 

      case TransformationResult.Busy: 
       deliveryOrderHandlerResult = DeliveryOrderHandlerResult.TransformationBusy; 

      case TransformationResult.MandatoryTransformationFailed: 
       deliveryOrderHandlerResult = DeliveryOrderHandlerResult.MandatoryTransformationFailed; 

      default: 
       throw new Exception(--unknown enum value --); 
     } 
    } 

    return deliveryOrderHandlerResult; 
} 

DeliverDocumentToExternalSystem

pseudo: 
- Create Delivery package by reading data from database and transformed files from disk 
- Send package to external system 

正如你可以看到有很多可能出錯;數據庫連接失敗,wcf服務調用失敗,文件不存在等。

我希望我能避免這種情況:

QueueHandler

private static void HandleQueueMessage(Message message) 
{ 
    var deliveryOrder = deserialize(message.body); 

    var deliveryOrderHandler = new DeliveryOrderHandler(); 

    try 
    { 
     var result = deliveryOrderHandler.Execute(deliveryOrder.PubId); 

     switch(result) 
     { 
      case DeliveryOrderHandlerResult.Success: 
       // remove message from queue 

      case DeliveryOrderHandlerResult.NotStarted: 
       // resent message to queue 

      case DeliveryOrderHandlerResult.MandatoryTransformationFailed: 
       // send message to deadletterqueue 

      case ... 
       // handle 

      case ... 
       // handle 

     } 
    } 
    pseudo catches: 
    catch (DatabaseNotFoundexception ex) 
    { 
     // resent message to queue 
    } 
    catch (ExternalWcfServiceDownException ex) 
    { 
     // resent message to queue 
    } 
    catch (FileNotFoundException ex) 
    { 
     // send message to deadletterqueue 
    } 
    catch (...) 
    { 
     // handle 
    } 
    catch (...) 
    { 
     // handle 
    } 
} 
+0

你有什麼迄今爲止關於代碼,你可以展示,從而使他人可以提供一個更好的方法..如果您確實張貼了這種性質..它可能會在計算器上的代碼審查部分可以提供最好的服務代碼。 – MethodMan

回答

1
  1. ...這夫妻主級一路到最低等級。

不是。它將您的主類耦合到異常類型。是的,如果您更改了異常,則需要將處理更改爲更高,但耦合處於異常級別。

3是不是,你可以忘記檢查返回一個不錯的選擇。您最終會遇到與您在選項1中列出的完全相同的問題,就好像您將結果對象更改爲低位一樣,您需要對主類進行更改...

例外情況被視爲superioroption, 「T不得不檢查找出是否發生了錯誤。

+0

很抱歉,如果我誤解你了,但基本上在大尺度水平,你推薦使用'解析()的''代替的TryParse()',在.net中的下來說的。 –

+0

@IlyaIvanov - 你在說什麼?您的評論似乎並不涉及這裏的問題和答案。 – Oded

+0

我問過同樣的問題,當你在鏈接了:「異常或錯誤代碼」。一種方法是依靠返回值,另一種方法 - 拋出異常拋出方法。 –