2012-04-25 55 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()); 
        }