5

我使用 Struts 1.2.4 继承了这个巨大的遗留 Java Web 应用程序。我有一个关于行动的具体问题。大多数页面只有一个 Action,而 processExecute() 方法是可怕的怪物(非常长且大量基于请求参数的嵌套 if 语句)。

鉴于动作是命令模式的一种实现,我正在考虑将这些动作拆分为每个用户手势一个动作。不过,这将是一次大型重构,我想知道:

  1. 这是正确的方向吗?
  2. 有没有我可以采取的中间步骤,一种处理单体操作内部混乱的模式?也许动作中的另一个命令模式?
4

7 回答 7

9

我的处理方式是:

  • 不要“一次做所有事情”
  • 每当你改变任何东西时,让它比你发现它更好
    • 用单独的 Action 实现替换条件是一个步骤。
    • 更好的是:使您的实现与 Action 类分开,以便您在更改框架时可以使用它
    • 保持您的新 Command 实现绝对不引用 Struts,使用您的新 Actions 作为围绕这些实现的 Wrapper。
    • 您可能需要为您的 Struts ActionForms 提供接口,以便在不复制所有数据的情况下传递它们。另一方面-您可能希望传递通常是一堆字符串的 ActionForms 以外的其他对象(请参阅有关Struts 1.2 ActionForms的其他问题)
  • 开始将零件迁移到更新更好的技术。Struts 1.2 一出来就很棒,但绝对不是你想要永远支持的。现在有几代更好的框架。

肯定还有更多——抱歉,我没时间了……

于 2008-10-16T18:19:28.167 回答
5

在我看来,Struts Actions 中根本不应该有太多代码。他们应该直接与请求和响应交互——从表单或请求参数中获取一些数据,将这些信息传递给服务层,然后将一些内容放入 Response 对象中,或者将一些数据保存在用户的会话中。

我建议不要使用动作类进行继承。起初这听起来是个好主意,但我认为迟早你会意识到你在做一些事情,而不是让代码库变得健壮。Struts 有足够的基本操作,如果您正在创建新的操作,您可能在 Web 层中获得了不应该存在的代码。

这只是我个人的经验。

于 2008-10-17T02:57:43.253 回答
2

我以前处理过这种类型的事情。一个好的第一步是将另一个基类插入到 Action 和一个原始的怪异动作类(我们称之为 ClassA)之间的继承链中。特别是如果你没有时间一次做所有事情。然后,您可以开始将功能块提取到较小的并行操作类(ClassB、ClassC)中。原始 ClassA 和新重构的类之间共有的任何东西都可以拉入新的基类中。所以层次结构现在看起来像这样:

Original Hierarchy:      New Hierarchy:

     Action                   Action
       |                        |
       |                      BaseA
  (old)ClassA                   |
                       +--------+----------+
                       |        |          |
                   ClassB (new)ClassA   ClassC
于 2008-10-17T01:59:26.693 回答
2
  1. 一次使用一种方法
  2. 记录一些您可以稍后回放的测试用例。 此处的示例(确保在代码中点击尽可能多的路径,即页面上调用此操作的所有用户手势)
  3. 通过创建更小的方法来做更小的事情,重构方法以降低其复杂性。
  4. 执行此操作时重新运行测试

至此,你已经重构了巨大的恼人方法的版本。 现在您可以真正开始创建特定的操作了。

您可以将新重构的类用作基类,并使用那些重构的小方法将每个特定操作作为子类实现。

完成此操作后,您应该对类之间共享的逻辑有一个很好的了解,并且可以根据需要上拉或下推这些方法。

It's not fun, but if you will be working on the codebase for a while, it will save you time and headaches.

于 2008-10-17T16:21:35.520 回答
1

棘手的问题,但典型的早期 Web 应用程序开发。

首先,您需要开始思考哪些逻辑构成业务行为,哪些逻辑构成“流程”(即用户看到的内容),以及哪些逻辑获取他看到的内容。

您不必走工厂和接口之类的路线;追溯实现的用处要小得多......但是将业务逻辑和数据检索逻辑整合到某种委托中......并让struts动作根据该逻辑的成功/失败来确定页面流。

从那里你只需要花几个星期的时间把它磨出来

于 2008-10-16T18:26:49.900 回答
1

一个长方法永远不会好,除非它恰好是一个单独的 switch 语句,其中的情况很短(令牌解析或类似的东西)。

您至少可以将 long 方法重构为具有描述性名称的较小方法。

如果可能的话,您可以通过检查表单来识别它应该做什么来开始您的方法,然后通过 if/else 进入各种选项。但是没有嵌套的 if,那些往往会使代码不可读。只是

enum Operation {
  ADD, DELETE;
}

...

Operation operation = determineOperation(form);
if (operation == Operation.DELETE) { 
  doDelete(form); 
} else if (operation == Operation.ADD) {
  doAdd(form);
}

如果你能走得那么远,你的逻辑就会很好而且干净,你可以做任何你想做的重构。

困难的部分是让你的逻辑清晰,你可以逐步做到这一点。在您完全了解问题所在之前,不要选择模式。

于 2008-10-16T18:34:39.823 回答
1

如果您打算重构代码,您应该确保首先为现有代码编写测试,这样您就可以确保在开始重构后您没有更改它的功能。

于 2008-10-16T18:45:45.383 回答