.NET类重构困境

时间:2009-01-06 02:32:01

标签: c# .net oop refactoring

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

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. 我对基类的名称不太满意。它看起来很模糊,而且信息量不大(但我认为应用程序已经很好地定义,由框架保留,并且如果我使用它会造成严重的混淆,我想不到更好)。

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

  5. 所以我发出了求助,指导和建议的请求。你能获得的任何东西都非常感激。

    P.S。我在这里问这个,因为我经常这样做,作为我公司的唯一开发人员;我没有其他任何人反对这些想法。你们对这些东西有很多经验,如果我不求你的建议,那将是愚蠢的,所以我希望你们都能忍受我。提前谢谢!

3 个答案:

答案 0 :(得分:2)

以下是另一种重构方法:

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和一个具有方法的工厂,可以为您返回正确配置的应用程序。

答案 1 :(得分:0)

对我来说似乎很合理。

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

答案 2 :(得分:0)

我必须同意@Grauenwolf这似乎是合理的。

根据通用性,您可能希望提供一种机制来封装配置检索(一种拉出/设置命令行args的方法)或如何执行应用程序(同步或ASync)。

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