重构C#代码(帮助改进)

重构C#代码(帮助改进),c#,refactoring,C#,Refactoring,我需要帮助来重构这个代码示例的一些部分,从这里if(_obj是应用程序),所以这将是通用的 public override void Body(object _obj, object _objInPreviousState) { if (_obj != null) { string Message = ""; string Subject = "";

我需要帮助来重构这个代码示例的一些部分,从这里
if(_obj是应用程序)
,所以这将是通用的

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("aps@somedomain.com", emails.ToArray(), Message, Subject);
                    }
                    else if (app.ApplicationStatus != appInPreviousState.ApplicationStatus)
                    {
                        emailService().SendEmails("aps@somedomain.com", 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("aps@somedomain.com", emails.ToArray(), Message, Subject);
                    }
                    else if (product.ProductStatusType != prodInPreviousState.ProductStatusType)
                    {
                        emailService().SendEmails("aps@somedomain.com", 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("aps@somedomain.com", emails.ToArray(), Message, Subject);
                    }
                    else if (ces.Status != cesInPreviousState.Status)
                    {
                        emailService().SendEmails("aps@somedomain.com", 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("aps@somedomain.com", 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");
            }

        }
公共覆盖无效体(对象_obj,对象_objinproveiousstate)
{
如果(_obj!=null)
{
字符串消息=”;
字符串主语=”;
if(_objinproveiousstate==null)
{
var emailParams=this.Param作为字典;
如果(emailParams!=null)
{
Message=emailParams[“Message”];
主题=电子邮件参数[“主题”];
}
}
var emails=userRepository().GetForRoles(“RM”).Select(c=>c.Email);
如果(_obj是应用程序)
{
var-app=(应用程序)\u-obj;
var appInPreviousState=\u objInPreviousState作为应用程序;
如果(appInPreviousState==null)
{
emailService()。发送电子邮件(“aps@somedomain.com“、emails.ToArray()、消息、主题);
}
else if(app.ApplicationStatus!=appInPreviousState.ApplicationStatus)
{
emailService()。发送电子邮件(“aps@somedomain.com,emails.ToArray(),“应用程序:+app.ID+”更改的决策状态:“+Enum.GetName(typeof(AppStatus),app.ApplicationStatus),”检查以下应用程序:“+app.ID”;
}
}
如果(_obj是产品)
{
var乘积=(乘积)_obj;
var prodInPreviousState=_objInPreviousState作为产品;
if(prodInPreviousState==null)
{
emailService()。发送电子邮件(“aps@somedomain.com“、emails.ToArray()、消息、主题);
}
else if(product.ProductStatusType!=prodInPreviousState.ProductStatusType)
{
emailService()。发送电子邮件(“aps@somedomain.com,emails.ToArray(),“Product:+Product.ID+”for application“+Product.ApplicationID+”更改的决策状态:“+Enum.GetName(typeof(AppStatus),Product.ProductStatusType)”,检查以下应用程序:“+Product.ApplicationID”;
}
}
否则如果(对象为CES)
{
var ces=(ces)u obj;
var cesInPreviousState=_objInPreviousState作为CES;
if(cesInPreviousState==null)
{
emailService()。发送电子邮件(“aps@somedomain.com“、emails.ToArray()、消息、主题);
}
else if(ces.Status!=cesInPreviousState.Status)
{
emailService()。发送电子邮件(“aps@somedomain.com“、emails.ToArray(),“应用程序的CES”+CES.ApplicationID+“更改的决策状态:”+Enum.GetName(typeof(Cesstatus)、CES.status),“检查以下应用程序:”+CES.ApplicationID);
}
}
否则如果(_obj是注释)
{
var注释=(注释)\u obj;
emailService()。发送电子邮件(“aps@somedomain.com,email.ToArray(),“以下应用程序的注释:“+Comment.ApplicationID+”,消息:“+Comment.message+”,日期:“+Comment.CreatedDate”,以下应用程序的注释:“+Comment.ApplicationID”);
}
mLog.InfoLine(“发送电子邮件”);
}
}

您可能应该使用一些接口,我没有给您完整的代码,但有一个模式可以遵循

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());
}

您可以轻松改进两件事:

首先,反转一些
if
s以减少嵌套。特别是:

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

if (null == _obj) { return; }
... the rest ...
另外,将每个if/else主体提取到单独的方法中(您只需选择主体并从菜单中选择Refactor…extract Method)


最后,您应该能够将所有这些方法概括为一个包含更多参数的方法。

在这种情况下,您可以创建一个生成对象的工厂

这就是我重构的方式:

SomethingFactory生成AbstractSomething派生类(ConcreteSomethingA、ConcreteSomethingB等)。工厂根据“\u obj”和

将在具体类中实现,因此系统可以轻松地扩展

  • 如果(\u obj==null)返回,则将\u obj反转为
  • 声明替换为
    字符串。为空
  • 使用string.Format格式化包含大量连接的字符串
  • 将电子邮件地址提取到配置文件
  • 创建项目的接口

    public interface IEmail{
      string GetMessage();
      string GetSubject();
    }
    
  • 创建工厂以生成
    IEmail
    实例

  • 在一次通话中发送电子邮件

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

  • 你的意思是像
    generic
    中的generic吗(参见)或者仅仅使用
    接口
    进行多态性可以吗?基本上看一下代码中的重复项,并思考如何使这些重复项可重用。我要做的第一件事是将if语句更改为case语句,并将所有下线处理移到一个单独的方法中。您还可以查看coderash.M之类的工具也许这个问题可以放在更恰当的位置
     public void Body(object obj, object objInPreviousState)
        {
          const string Address= "aps@somedomain.com"; //extract to configuration
          IEmail item = GetEmailItem(_obj, _objInPreviousState);
          if(item != null) emailService().SendEmails( Address, emails.ToArray(), item.GetMessage(), item.GetSubject() );
        }