2009-01-06 33 views
3

所以我重构了我继承的遗留代码库,并且在此过程中,我找到了一个静态类,它封装了启动第三方应用程序的逻辑。它本质上是这样的(缩短为简洁起见,只显示一个应用程序):.NET类重构窘境

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文件中保留应用程序配置数据(它的路径和可执行文件名),并在我的应用程序启动时检查它的存在;当我的软件需要启动软件时,我想通过单一方法调用来完成,而不是通过代码构建命令行并尝试手动启动软件(就像它现在那样)。

所以我发出一个请求帮助,指导和建议。任何你可以profer非常感谢。

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

回答

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

0

对我来说似乎很合理。

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

+0

我曾考虑过这样做,但我们想要同步运行的一些应用程序以及其他异步运行的应用程序。因此需要重写Execute。 – 2009-01-06 02:48:13

+0

如果我没有预见到需要重写Execute,我可以逃脱一个类,只是在某种配置初始化事件期间传递信息。但这样,我得到了一种类型安全的Excel或PKZip应用程序对象。 – 2009-01-06 02:49:42

0

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

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

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

祝你好运,我希望这有助于。