0

我需要帮助来重构此代码示例的某些部分,if (_obj is Application)因此这将是通用的。

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

        }
4

4 回答 4

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());
}
于 2012-04-25T13:44:37.550 回答
1

您可以轻松改进两件事:

首先,反转一些ifs 以减少嵌套。尤其:

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

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

此外,将每个 if/else 主体提取到单独的方法中(您可以简单地选择主体并从菜单中选择 Refactor...Extract Method。

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

于 2012-04-25T13:46:40.687 回答
1

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

这就是我将如何重构:

SomethingFactory 产生 AbstractSomething 派生类(ConcreteSomethingA、ConcreteSomethingB 等)。工厂根据“_obj”和

public override void Body(object _obj, object _objInPreviousState)

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

于 2012-04-25T13:49:47.540 回答
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= "aps@somedomain.com"; //extract to configuration
          IEmail item = GetEmailItem(_obj, _objInPreviousState);
          if(item != null) emailService().SendEmails( Address, emails.ToArray(), item.GetMessage(), item.GetSubject() );
        }
    
于 2012-04-25T14:17:29.747 回答