【问题标题】:.NET Class Refactoring Dilemma.NET 类重构困境
【发布时间】:2009-01-06 02:32:00
【问题描述】:

所以我正在重构我继承的遗留代码库,在此过程中我发现了一个静态类,它封装了启动 3rd 方应用程序的逻辑。它基本上看起来像这样(为简洁起见,仅显示一个应用程序):

using System.IO;
using System.Configuration;
public static class ExternalApplications
{

   public string App1Path
   {
      get
      {
         if(null == thisApp1Path)
            thisApp1Path = Configuration.AppSettings.Get("App1Path");
         return thisApp1Path;
      }
   }
   private string thisApp1Path = null;

   public bool App1Exists() 
   {
      if(string.IsNullOrEmpty(App1Path))
         throw new ConfigurationException("App1Path not specified.");
      return File.Exists(App1Path);
   }

   public void ExecuteApp1(string args) 
   {
       // Code to launch the application.
   }

}

将外部应用程序与其余代码分开是一个很好的尝试,但我突然想到这可以进一步重构。我的想法是这样的:

using System.IO;
public abstract class ExternalApplicationBase
{

   protected ExternalApplicationBase()
   {
      InitializeFromConfiguration();
   }

   public string Path { get; protected set; }

   public bool Exists() 
   {
      if(string.IsNullOrEmpty(this.Path))
         throw new ConfigurationException("Path not specified.");
      return File.Exists(this.Path);
   }

   public virtual void Execute(string args)
   {
      // Implementation to launch the application
   } 

   protected abstract InitializeFromConfiguration();

}

public class App1 : ExternalApplicationBase
{

   protected virtual void InitializeFromConfiguration()
   {
      // Implementation to initialize this application from
      // the application's configuration file.
   }

 }

 public class App2 : ExternalApplicationBase
 {

   protected virtual void InitializeFromConfiguration()
   {
      // Implementation to initialize this application from
      // the application's configuration file.
   }

 }

我的担忧如下:

  1. 可能已经存在执行此操作的类、接口或其他构造,我只是没有偶然发现它。

  2. 对于我想做的事情来说,这可能有点矫枉过正。但是请注意,该应用程序至少使用了我迄今为止确定的三个独立的第 3 方应用程序(并且几乎肯定会弹出更多应用程序)。

  3. 我对基类的名称不太满意。它看起来很模糊,而且信息量不大(但我想不出比这更好的了,因为 Application 已经被很好地定义,由框架保留,如果我使用它会造成严重的混乱)。

  4. 我的想法是我希望能够将应用程序配置数据(它的路径和可执行文件名)保存在 App.Config 文件中,并在我的应用程序启动时检查它是否存在;当我的软件需要启动软件时,我想通过一个方法调用来完成,而不是使用代码构建命令行并尝试手动启动软件(就像目前一样)。

因此,我发送请求帮助、指导和建议。非常感谢您提供的任何内容。

附:我在这里问这个问题是因为我像往常一样在我的公司作为唯一的开发人员工作;我没有其他人可以反对这些想法。你们在这方面有很多经验,我不征求你们的意见是愚蠢的,所以我希望你们能容忍我。提前致谢!

【问题讨论】:

    标签: c# .net oop refactoring


    【解决方案1】:

    这是另一种重构方式:

    using System.IO;
    public class ExternalApplication
    {
       public ExternalApplication(string path)
       {
          this.Path = path;
       }
    
       public string Path { get; protected set; }
    
       public bool Exists() 
       {
          if(string.IsNullOrEmpty(this.Path))
             throw new ConfigurationException("Path not specified.");
          return File.Exists(this.Path);
       }
    
       public void Execute(string args)
       {
          // Implementation to launch the application
       } 
    }
    
    public class AppFactory
    {
       public ExternalApplication App1()
       {
          // Implementation to initialize this application from
          // the application's configuration file.
       }
    
       public ExternalApplication App2()
       {
          // Implementation to initialize this application from
          // the application's configuration file.
       }
    
       public ExternalApplication AppFromKey(string key)
       {
          // get from somewhere
       } 
     }
    

    在这种情况下,您只有一个类型 ExternalApplication 和一个工厂,该工厂具有为您返回正确配置的应用程序的方法。

    【讨论】:

    • 无论如何我都打算使用工厂;但这很好地消除了不必要的派生类型。我只需要添加一个额外的属性来处理它是否需要异步运行,并为其名称添加一个属性。谢谢!
    【解决方案2】:

    在我看来是合理的。

    我过去做过类似的事情,但我没有抽象基类。相反,我在构造函数中传入了应用程序路径。

    【讨论】:

    • 我想过这样做,但是我们希望一些应用程序同步运行,而其他一些则异步运行。因此需要可能覆盖 Execute。
    • 如果我没有预见到需要以这种方式覆盖 Execute,我可以只使用一个类,只需在某种配置初始化事件中传递信息。但是这样,我得到了一种类型安全的 Excel 或 PKZip 应用程序对象。
    【解决方案3】:

    我不得不同意@Grauenwolf 的观点,这似乎是合理的。

    根据共同点,您可能希望提供一种机制来封装配置检索(一种提取/设置命令行参数的方法)或如何执行应用程序(同步或异步)。

    1. 如果您发现一个已经存在,请尝试在其周围放置一个包装器并继续。
    2. 添加这个额外的层并没有太多的努力,并且有助于更好 单独的应用程序关注点。我觉得还可以,可以帮忙 通过模拟提高可测试性。
    3. AppLauncherBase 还是 AppExecutorBase?没有理由 为什么应用程序需要是外部的。不是有史以来最好的名字,但我会尝试封装类的目的,启动/执行应用程序。
    4. 您可能需要考虑在 App.Config 中定义用于定义配置数据/应用程序路径信息的约定,然后在基类中实现用于检索它的逻辑作为默认值。

    祝你好运,我希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-21
      • 2011-05-26
      • 2010-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多