java - 如何逐步从大型系统中的遗留内容中恢复?

标签 java dependency-injection refactoring legacy-code code-cleanup

我们的团队得到了一个遗留系统,需要进一步维护和开发。 因为这是真正的“遗留”东西,所以测试的数量真的非常少,而且大部分都是废话。这是一个具有 Web 界面的应用程序,因此有容器管理的组件以及普通的 Java 类(不依赖于任何框架等),它们随时都是“新版”的。

当我们使用这个系统时,每次我们接触到给定的部分时,我们都会尝试将所有这些东西分解成更小的部分,发现并重构依赖关系,推送依赖关系而不是将它们拉入代码中。

我的问题是如何使用这样的系统,打破依赖关系,使代码更易于测试等?何时停止以及如何处理?

举个例子:

public class BillingSettingsAction {

    private TelSystemConfigurator configurator;
    private OperatorIdDao dao;

    public BillingSettingsAction(String zoneId) {
        configurator = TelSystemConfiguratorFactory.instance().getConfigurator(zoneId);
        dao = IdDaoFactory.getDao();
        ...
    }

    // methods using configurator and dao
}

这个构造函数肯定做的太多了。还要测试它以进一步重构它需要使用 PowerMock 等进行魔术。我要做的是将其更改为:

public BillingSettingsAction(String zone, TelSystemConfigurator configurator, OperatorIdDao dao) {
    this.configurator = configurator;
    this.dao = dao;
    this.zone = zone;
}

或者仅提供构造函数设置区域和依赖项的 setter 。

我看到的问题是,如果我在构造函数中提供依赖项,我仍然需要在某个地方提供它们。所以它只是将问题提升了一个层次。我知道我可以创建工厂来连接所有依赖项,但是接触应用程序的不同部分会导致每个工厂都有不同的工厂。我显然不能一次重构所有应用程序并引入例如那里有 Spring 。

公开 setter(可能提供默认实现)是类似的,而且它就像只为测试添加代码。

所以我的问题是您是如何处理的?如何在不一口气完成的情况下使对象之间的依赖关系更好、更可读、更可测试?

最佳答案

我最近刚开始阅读 Michael Feathers 的“有效地使用遗留代码”。 这本书基本上是对你的问题的回答。它提供了非常实用的“金 block ”和技术,可以逐步对遗留系统进行测试并逐步改进代码库。

导航可能有点困惑,因为这本书通过指向特定技术来引用自己,几乎从第 1 页开始,但我发现到目前为止内容非常有用。

我不隶属于作者或类似的任何人,只是我面临着类似的情况,并且发现这是一个非常有趣的资源。

HTH

关于java - 如何逐步从大型系统中的遗留内容中恢复?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10180220/

相关文章:

java - 变量声明 - 尽可能使用修饰符 'final'。是的,类和方法怎么了?

java.lang.NoSuchMethodError : com. mongodb.MongoClient.<init>(Ljava/util/List;Lcom/mongodb/MongoCredential;Lcom/mongodb/MongoClientOptions;)V]

python - 将此 Python 结构的值合并到单个字典中的更快方法是什么?

objective-c - 台风:注入(inject) View Controller 提供程序

c++ - 从命令行使用 Eclipse CDT

java - java中的双括号初始化

java - 为 Guava 设置 PITest

java - 如何避免过多的 hibernate 刷新到数据库

dependency-injection - 在 Guice 模块中获取实例

c# - 将 IOptions<> 注入(inject)静态类