如何应对可怕的Struts Actions?
我使用 Struts 1.2.4 继承了这个巨大的遗留 Java Web 应用程序。 我有一个关于行动的具体问题。 大多数页面只有一个 Action,并且 processExecute() 方法是可怕的怪物(非常长且基于请求参数的大量嵌套 if 语句)。
鉴于操作是命令模式的一种实现,我正在考虑将这些操作拆分为每个用户手势一个操作。 但这将是一次大规模的重构,我想知道:
- 这是正确的方向吗?
- 我是否可以采取中间步骤,一种处理整体操作内部混乱的模式? 也许动作中还有另一个命令模式?
I inherited this gigantic legacy Java web app using Struts 1.2.4. I have a specific question regarding Actions. Most of the pages have exactly one Action, and the processExecute() methods are hideous monsters (very long and tons of nested if statements based on request parameters).
Given that Actions are an implementation of the command pattern, I'm thinking to split these Actions into one Action per user gesture. This will be a large refactoring though, and I'm wondering:
- Is this the right direction?
- Is there an intermediate step I could take, a pattern that deals with the mess inside the monolithic actions? Maybe another command pattern inside the Action?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我处理这个问题的方法是:
肯定还有更多 - 抱歉,我的时间不多了......
My way of dealing with this would be:
There's definitely more - Sorry, I'm running out of time here...
在我看来,Struts Actions 中根本不应该包含太多代码。 他们应该直接与请求和响应交互 - 从表单或请求参数中获取一些数据,将该信息传递给服务层,然后将一些内容放入 Response 对象中,或者可能在用户会话中保存一些数据。
我建议不要使用操作类进行继承。 一开始这听起来是个好主意,但我认为迟早你会意识到你是在硬塞东西,而不是真正使代码库变得健壮。 Struts 有足够的基本操作,如果您要创建新的操作,您可能在 Web 层中获得了不应该存在的代码。
这只是我的个人经历。
Struts Actions, in my mind, shouldn't have very much code in them at all. They should just interact directly with the request and response - take some data from a form or a request parameter, hand that info off to the Service Layer, and then put some stuff in a Response object or maybe save some data in the user's session.
I'd recommend staying away from doing inheritance with action classes. It sounds like a good idea at first but I think sooner or later you realize that you're shoe-horning things more than you're actually making the code base robust. Struts has enough base actions as is, if you're creating new ones you've probably got code in the web layer that shouldn't be there.
That is just my personal experience.
我以前处理过这类事情。 好的第一步是将另一个基类插入到 Action 和一个原始的巨大操作类(我们称之为 ClassA)之间的继承链中。 特别是如果您没有时间一次完成所有事情的话。 然后,您可以开始将功能片段提取到更小的并行操作类(ClassB、ClassC)中。 原始 ClassA 和新重构类之间的任何共同点都可以提取到新的基类中。 所以层次结构现在看起来像这样:
I've dealt with this type of thing before. A good first step is to insert another base class into the inheritance chain between Action and one of the original monstrous action classes (lets call it ClassA). Especially if you don't have time to do everything at once. Then you can start pulling out pieces of functionality into smaller parallel Action classes (ClassB, ClassC). Anything that's common between the original ClassA and the new refactored classes can be pulled up into the new base class. So the hierarchy now looks like this:
此时,您已经重构了令人讨厌的巨大方法的版本。 现在您实际上可以开始创建特定操作。
您可以使用新重构的类作为基类,并使用这些重构的小方法将每个特定操作作为子类实现。
完成此操作后,您应该对类之间共享的逻辑有一个很好的了解,并且可以根据需要上拉或下推这些方法。
这并不有趣,但如果您将在代码库上工作一段时间,它将节省您的时间和麻烦。
At this point, you have refactored version of the big huge annoying method. Now you can actually start creating specific actions.
You can use your newly refactored class as a base class, and implement each specific action as a subclass using those refactored small methods.
Once you've done this, you should have a good picture of the logic shared between the classes and can pull-up or push-down those methods as needed.
It's not fun, but if you will be working on the codebase for a while, it will save you time and headaches.
这是一个棘手的问题,但却是早期 Web 应用程序开发的典型问题。
首先你需要开始思考哪些逻辑构成了业务行为,哪些逻辑构成了“流”(即用户看到的内容),以及哪些逻辑获取了他所看到的内容。
您不必沿着工厂和接口之类的路线走下去; 追溯实现的用处要小得多...但是将业务逻辑和数据检索逻辑合并到某种委托中...并让 struts 操作根据该逻辑的成功/失败来确定页面流。
从那里你只需要花几周的时间来磨练它
Tough problem but typical of early web app development.
First things first you need to start thinking about which logic constitutes business behavior, which logic constitutes "flow" (i.e. what the user sees), and which logic gets the content for what he sees.
You don't have to go down the route of factories and interfaces and all that; retroactive implementation is far less useful... but consolidating business logic and data retrieval logic into delegates of some kind... and leaving the struts actions to determine page flow based on success/failure of that logic.
From there you just have to take a few weeks and grind it out
一个长方法永远都不好,除非它碰巧是单个 switch 语句,其中 case 非常短(令牌解析或类似的东西)。
您至少可以将长方法重构为具有描述性名称的较小方法。
如果可能的话,您可以通过检查表单来识别它应该做什么来开始您的方法,然后使用 if/else 找到各种选项。 虽然没有嵌套的 if,但这些往往会使代码不可读。 只要
你能做到这一点,你的逻辑就干净整洁,你就可以做任何你想做的重构。
困难的部分是让你的逻辑清晰,你可以分步骤做到这一点。 在您确切了解问题所在之前,不要选择模式。
One long method is never good, unless it happens to be a single switch statement where the cases are very short (token parsing or something like that).
You could at least refactor the long method into smaller methods with descriptive names.
If at all possible you could start your method with recognizing what it is it should do by examining the form, and then if/else your way to the various options. No nested ifs though, those tend to make code unreadable. Just
If you can go that far you have your logic nice and clean and you can do whatever refactoring you want.
The hard part is to get your logic clear, and you can do that in steps. Don't choose a pattern untill you understand exactly what your problem is.
如果您计划重构代码,您应该确保首先为现有代码编写测试,这样您就可以确保在开始重构后没有更改它的功能。
If you're planning to refactor the code you should make sure to write tests for the existing code first so you can be sure you haven't altered the functionality of it once you start refactoring.