【问题标题】:Refactoring help with IfsIfs 的重构帮助
【发布时间】:2010-11-19 16:36:24
【问题描述】:

我已经研究这段代码一段时间了,出于某种原因,所有的 if 和一堆重复的代码都让我发疯了。 有没有更好更清洁的方法来做到这一点?

public Program(string[] args)
    {
        try
        {
            WriteToLogFile("Starting ImportTask");
            if (args.Length == 0)
            {
                Import(DateTime.Now,DateTime.Now);
                MarkRecordsAsDeleted();
            }
            else if (args.Length == 1)
            {
                DateTime dateToImport;
                bool isValidDate = DateTime.TryParse(args[0], out dateToImport);
                if (isValidDate)
                {
                    Import(dateToImport,dateToImport);
                    MarkRecordsAsDeleted();
                }
                else
                    WriteToLogFile(String.Format("The Import date specified was invalid. - {0}", args[0]));
            }
            else if (args.Length == 2)
            {
                DateTime importStartDate;
                bool isValidStartDate = DateTime.TryParse(args[0], out importStartDate);
                DateTime importEndDate;
                bool isValidEndDate = DateTime.TryParse(args[0], out importEndDate);
                if (isValidStartDate && isValidEndDate)
                {
                    if (importStartDate > importEndDate)
                    {
                        WriteToLogFile(String.Format("Invalid date range provided. Start date = {0} End date {1}",importStartDate,importEndDate));
                        return;
                    }
                    Import(importStartDate, importEndDate);
                    MarkRecordsAsDeleted();
                }
                else
                    WriteToLogFile(String.Format("The Import date specified was invalid. - {0}", args[0]));
            }
            else
            {
                WriteToLogFile("Invalid Command Line Parameters Specified");
            }

        }
        catch (Exception ex)
        {
            WriteToLogFile("Error in Import Process = " + ex.StackTrace);
        }
    }

【问题讨论】:

  • 我强烈建议您始终显示或存储 ex.ToString()。你丢掉了很多好的数据。
  • 会的!感谢您的提醒。

标签: refactoring .net-2.0


【解决方案1】:

你在这里得到的是一个有两个参数的函数,它期望可以解析为日期的字符串。如果缺少第二个参数,则使用第一个参数;如果缺少第一个,则使用 DateTime.Now。

因此,编写一个带有两个日期的双参数函数。称它为。大致如下:

switch(args.length) {
    case 0: myFunc(DateTime.Now, DateTime.Now); break;
    case 1: myFunc(toDate(args[0]), toDate(args[0])); break;
    case 2: myFunc(toDate(args[0]), toDate(args[1])); break;
}

顺便说一句,您似乎没有在函数中引用 args[1];这可能是一个错误。

【讨论】:

    【解决方案2】:

    这是第一关:

    public Program(string[] args)
    {
        try
        {
            WriteToLogFile("Starting ImportTask");
            DateTime startTime;
            DateTime endTime;
            GetDateRange(args, out startTime, out endTime);
    
            Import(startTime, endTime);
            MarkRecordsAsDeleted();
        }
        catch (Exception ex)
        {
            WriteToLogFile("Error in Import Process = " + ex);
            throw;
        }
    }
    
        private static void GetDateRange(string[] args, out DateTime startTime, out DateTime endTime)
        {
            switch (args.Length)
            {
                case 0:
                    startTime = DateTime.Now;
                    endTime = DateTime.Now;
                    break;
                case 1:
                    {
                        DateTime dateToImport;
                        var isValidDate = DateTime.TryParse(args[0], out dateToImport);
                        if (!isValidDate)
                        {
                            throw new Exception(
                                String.Format(
                                    "The Import date specified was invalid. - {0}",
                                    args[0]));
                        }
    
                        startTime = dateToImport;
                        endTime = dateToImport;
                    }
                    break;
                case 2:
                    {
                        DateTime importStartDate;
                        bool isValidStartDate = DateTime.TryParse(args[0], out importStartDate);
                        DateTime importEndDate;
                        bool isValidEndDate = DateTime.TryParse(args[1], out importEndDate);
                        if (!isValidStartDate || !isValidEndDate)
                        {
                            throw new Exception(
                                String.Format(
                                    "The Import dates specified was invalid. - {0}, {1}",
                                    args[0], args[1]));
                        }
    
                        if (importStartDate > importEndDate)
                        {
                            throw new Exception(
                                String.Format(
                                    "Invalid date range provided. Start date = {0} End date {1}",
                                    importStartDate, importEndDate));
                        }
    
                        startTime = importStartDate;
                        endTime = importEndDate;
                    }
                    break;
                default:
                    throw new Exception("Invalid Command Line Parameters Specified");
            }
        }
    

    【讨论】:

      【解决方案3】:

      看看strategy pattern。这将需要一些重大的重构和相当多的新类,但它应该可以解决您想要解决的问题。

      暂时不考虑花哨的名称,这个想法实际上很简单。

      您有一个抽象或接口类,它定义了一个要调用的方法。然后,您有几个派生类,您可以将 if 的内容移动到其中。

      作为一个简单的示例,让我们执行以下操作:

       interface Ifoo
       {
           void myAction();
       }
      
       class MyCustomActionBar : Ifoo
        {
            public void myAction()
            {
                //.... details ... - Contents of single if statement.
            }
        }
      
       class MyCustomActionTar : Ifoo
        {
            public void myAction()
            {
                //.... details ... - Contents of next but single if statement.
            }
        }
      

      一旦你设置了所有的类,你就可以将你的 if 更改为如下所示。

      public Program(string[] args)
      {
         Ifoo _myFoo;
          try
          {
              WriteToLogFile("Starting ImportTask");
              if (args.Length == 0)
              {
                  _myFoo = new MyCustomActionBar();
              }
              else if (args.Length == 1)
              {
                  _myFoo = new MyCustomActionTar ();
              }
              //... etc....
              }
              else
              {
                    _myFoo = new MyErrorAction(); //Definition not illustrated above
              }
              _myFoo.myAction();   //Getting your actual return values and stuff would be design details that I'm leaving out.
      
          }
          catch (Exception ex)
          {
               //...
          }
      }
      

      请原谅示例中的错误或拼写错误,我很快就完成了。这只是为了说明一般想法,以简单地介绍 Wikipedia 文章以提供快速快照的想法。细节会涉及更多。

      【讨论】:

      • 您还可以查看工厂模式,因为它被认为(至少在我看来)与这种模式密切相关。
      【解决方案4】:

      这是我的两分钱。请注意,DateTime 解析失败默认返回 DateTime.Now,这很可能不是您想要的。如果是这样,请按照您的意愿处理。从您的源代码中,您记录它并完成而不会引发错误。根据您处理问题的方式,您可能希望在 (startDate > endDate) 时执行相同的操作。

      以下是未经测试的代码...

      public Program(string[] args)
      {
          WriteToLogFile("Starting ImportTask");
      
          DateTime startDate = DateTime.Now;
          DateTime endDate = DateTime.Now;
      
          if (args.Length > 0)                    
              if (!DateTime.TryParse(args[0], out startDate)
                  WriteToLogFile(string.format("Warning: StartDate argument, {0}, is invalid; value has reverted to current Date/Time.", args[0]) );
      
          if (args.Length > 1)
              if (!DateTime.TryParse(args[1], out endDate)
                  WriteToLogFile(string.format("Warning: EndDate argument, {0}, is invalid; value has reverted to current Date/Time.", args[]) );
      
          if (startDate > endDate)
          {       
              WriteToLogFile(String.Format("Invalid date range provided. Start date = {0} End date {1}",importStartDate,importEndDate));
              return;
          }
      
          Import(startDate, endDate);
          MarkRecordsAsDeleted();
      }
      

      【讨论】:

        猜你喜欢
        • 2012-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多