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

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

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

解决方案

我处理这个问题的方法是:

  • 不要“一次做所有事情”
  • 每当你改变任何东西时,让它比你发现它时更好
    • 用单独的 Action 实现替换条件是第一步。
    • 更好的是:将您的实现与 Action 类分开,以便在更改框架时可以使用它
    • 保留新的命令实施 绝对地 如果不引用 Struts,请使用新的 Actions 作为这些实现的包装器。
    • 您可能需要为 Struts ActionForm 提供接口,以便在不复制所有数据的情况下传递它们。另一方面 - 您可能想要传递除 ActionForms 之外的其他对象,这些对象通常是一堆字符串(请参阅关于 Struts 1.2 动作表单)
  • 开始将零件迁移到更新更好的技术。Struts 1.2 刚推出时非常棒,但绝对不是您想要永远支持的。现在有几代更好的框架。

肯定还有更多 - 抱歉,我的时间不多了......

其他提示

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

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

这只是我的个人经历。

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

Original Hierarchy:      New Hierarchy:

     Action                   Action
       |                        |
       |                      BaseA
  (old)ClassA                   |
                       +--------+----------+
                       |        |          |
                   ClassB (new)ClassA   ClassC
  1. 一次一个方法
  2. 记录一些您可以稍后播放的测试用例。 此处示例(确保尽可能多地浏览代码中的路径,即调用此操作的页面上的所有用户手势)
  3. 通过创建较小的方法来重构该方法以降低其复杂性。
  4. 在您执行此操作时重新运行测试
  5. 此时,您已经重构了巨大的烦人方法。 现在您实际上可以开始创建特定的操作。

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

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

    这并不好玩,但是如果您将在代码库上工作一段时间,它将为您节省时间和麻烦。

难题但是早期Web应用程序开发的典型问题。

首先,您需要首先考虑哪种逻辑构成商业行为,哪种逻辑构成“流动”。 (即用户看到的内容),以及哪些逻辑获取他所看到的内容。

您不必沿着工厂和接口的路线走下去;追溯实现远没那么有用......但是将业务逻辑和数据检索逻辑整合到某种代理中......并留下struts动作来确定基于该逻辑成功/失败的页面流。

从那里你只需要几个星期就把它磨出来

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

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

如果可能的话,你可以通过检查表单来识别它应该做什么来启动你的方法,然后你可以通过各种选项来实现。虽然没有嵌套ifs,但这些代码往往使代码不可读。只是

enum Operation {
  ADD, DELETE;
}

...

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

如果你可以走得那么远,那么你的逻辑很干净,你可以做任何想要的重构。

困难的部分是让你的逻辑清晰,你可以逐步完成。不要选择一个模式,直到你明白你的问题是什么。

如果您计划重构代码,则应首先确保为现有代码编写测试,以便在开始重构后确定没有更改其功能。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top