2012-04-25 54 views
0

我需要幫助來重構此代碼示例的一些部分,其中if (_obj is Application)因此這將是通用的。重構C#代碼(幫助改進)

public override void Body(object _obj, object _objInPreviousState) 
     { 

      if (_obj != null) 
      { 
       string Message = ""; 
       string Subject = ""; 
       if (_objInPreviousState == null) 
       { 
        var emailParams = this.Param as Dictionary<string, string>; 
        if (emailParams != null) 
        { 
         Message = emailParams["Message"]; 
         Subject = emailParams["Subject"]; 
        } 
       } 
       var emails = userRepository().GetForRoles("RM").Select(c => c.Email); 
       if (_obj is Application) 
       { 
        var app = (Application)_obj; 
        var appInPreviousState = _objInPreviousState as Application; 
        if (appInPreviousState == null) 
        { 
         emailService().SendEmails("[email protected]", emails.ToArray(), Message, Subject); 
        } 
        else if (app.ApplicationStatus != appInPreviousState.ApplicationStatus) 
        { 
         emailService().SendEmails("[email protected]", emails.ToArray(), "Application: " + app.ID + " changed decision status: " + Enum.GetName(typeof(AppStatus), app.ApplicationStatus), "Check following application: " + app.ID); 
        } 
       } 
       else if (_obj is Product) 
       { 
        var product = (Product)_obj; 
        var prodInPreviousState = _objInPreviousState as Product; 
        if (prodInPreviousState == null) 
        { 
         emailService().SendEmails("[email protected]", emails.ToArray(), Message, Subject); 
        } 
        else if (product.ProductStatusType != prodInPreviousState.ProductStatusType) 
        { 
         emailService().SendEmails("[email protected]", emails.ToArray(), "Product: " + product.ID + " for application " + product.ApplicationID + " changed decision status: " + Enum.GetName(typeof(AppStatus), product.ProductStatusType), "Check following application: " + product.ApplicationID); 
        } 
       } 

       else if (_obj is CES) 
       { 
        var ces = (CES)_obj; 
        var cesInPreviousState = _objInPreviousState as CES; 
        if (cesInPreviousState == null) 
        { 
         emailService().SendEmails("[email protected]", emails.ToArray(), Message, Subject); 
        } 
        else if (ces.Status != cesInPreviousState.Status) 
        { 
         emailService().SendEmails("[email protected]", emails.ToArray(), "CES for application " + ces.ApplicationID + " changed decision status: " + Enum.GetName(typeof(CesStatuses), ces.Status), "Check following application: " + ces.ApplicationID); 
        } 
       } 
       else if (_obj is Comment) 
       { 
        var comment = (Comment)_obj; 
        emailService().SendEmails("[email protected]", emails.ToArray(), "Comment for the following application: " + comment.ApplicationID + " with message: " + comment.Message + " on date: " + comment.CreatedDate, "Comment for the following application: " + comment.ApplicationID); 
       } 
       mLog.InfoLine("Sendet Email"); 
      } 

     } 
+0

你意思是通用的,如'Generic '(參見http://msdn.microsoft.com/en-us/library/512aeb7t(v=vs.80).aspx)或只是使用'接口'多態性罰款? – StuperUser 2012-04-25 13:43:59

+0

基本上看你的代碼中的重複項目,並考慮如何使這些可重用。我要做的第一件事是將if語句更改爲case語句,並將所有下線處理移至單獨的方法中。你也可以看看Coderush這樣的工具。 – Brian 2012-04-25 13:45:08

+0

也許這個問題可以更好地放在http://codereview.stackexchange.com – 2012-04-25 13:47:30

回答

4

您應該可能使用一些接口,我沒有給你完整的代碼,但要遵循的模式。

interface IStatusItem 
{ 
    void SendEmails(EmailService service); 
} 

public class Product : IStatusItem 
{ 
    public void SendEmails(EmailService service) 
    { 
     // Send Email 
    } 
} 

public class Application : IStatusItem 
{ 
    public void SendEmails(EmailService service) 
    { 
     // Send Email 
    } 
} 

然後你的主代碼並不需要所有的if塊。它只是調用實現IStatusItem的實例。顯然你需要在那裏添加以前的狀態。

override void Body(object _obj, object _objInPreviousState) 
{ 
    IStatusItem sItem = obj as IStatusItem; 
    if(sItem != null) 
     sItem.SendEmails(emailService()); 
} 
1

有兩件事情,你可以輕鬆地提高:

首先,反轉一些if S的減少嵌套。特別是:

if (_obj != null) { ... the entire function ... } 

可以是

if (null == _obj) { return; } 
... the rest ... 

另外,提取各的的if/else機構成單獨的方法(你可以簡單地選擇身體,並選擇重構......從菜單中提取方法。

最後,你應該能夠概括所有這些方法到一個單一的一個需要一些更多的參數。

1

在這種情況下,你可以做一個廠是全國生產es物體。

這是如何我將重構:

SomethingFactory產生AbstractSomething派生類(ConcreteSomethingA,ConcreteSomethingB等)。這家工廠生產的ConcreteSomethings視「_obj」和

public override void Body(object _obj, object _objInPreviousState) 

將在具體的類來實現這樣的系統可以easely擴展

1
  1. 逆_obj到if (_obj == null) return;
  2. 更換""聲明成string.Empty
  3. 使用string.Format格式化大量串聯的字符串
  4. 提取電子郵件地址的配置文件
  5. 創建項目的接口

    public interface IEmail{ 
        string GetMessage(); 
        string GetSubject(); 
    } 
    
  6. 創建工廠產生IEmail實例

  7. 發送電子郵件在一個單一的通話

    public void Body(object obj, object objInPreviousState) 
        { 
         const string Address= "[email protected]"; //extract to configuration 
         IEmail item = GetEmailItem(_obj, _objInPreviousState); 
         if(item != null) emailService().SendEmails(Address, emails.ToArray(), item.GetMessage(), item.GetSubject()); 
        }