How to deal with monstrous Struts Actions? - java

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?

My way of dealing with this would be:
dont do 'everything at once'
whenever you change anything, leave it better than you found it
replacing conditionals with separate Action implementations is one step.
Better yet: Make your implementations separate from the Action classes so that you can use it when you change frameworks
Keep your new Command implementation absolutely without references to Struts, use your new Actions as Wrapper around these implementations.
You might need to provide interfaces to your Struts ActionForms in order to pass them around without copying all the data. On the other hand - you might want to pass around other objects than ActionForms that are usually a bunch of Strings (see your other question about Struts 1.2 ActionForms)
start migrating parts to newer & better technology. Struts 1.2 was great when it came out, but is definitely not what you want to support in eternity. There are some generations of better frameworks now.
There's definitely more - Sorry, I'm running out of time here...

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.

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:
Original Hierarchy: New Hierarchy:
Action Action
| |
| BaseA
(old)ClassA |
+--------+----------+
| | |
ClassB (new)ClassA ClassC

Go one method at a time
Record some test cases you can play back later. Example here (make sure to hit as many paths through the code as you can, i.e. all user gestures on the page that call this action)
refactor the method to reduce its complexity by creating smaller methods that do smaller things.
Re-run tests as you do 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.

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

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
enum Operation {
ADD, DELETE;
}
...
Operation operation = determineOperation(form);
if (operation == Operation.DELETE) {
doDelete(form);
} else if (operation == Operation.ADD) {
doAdd(form);
}
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.

Related

combined vs. separate backend calls

I try to figure out the best solution for a use case I'm working on. However, I'd appreciate getting some architectural advice from you guys.
I have a use case where the frontend should display a list of users assigned to a task and a list of users who are not assigned but able to be assigned to the same task.
I don't know what the better solution is:
have one backend call which collects both lists of users and sends them
back to the frontend within a new data class containing both lists.
have two backend calls which collect one of the two lists and send them
back separately.
The first solution's pro is the single backend call whereas the second solution's pro is the reusability of the separate methods in the backend.
Any advice on which solution to prefer and why?
Is there any pattern or standard I should get familiar with?
When I stumble across the requirement to get data from a server I start with doing just a single call for, more or less (depends on the problem domain), a single feature (which I would call your task-user-list).
This approach saves implementation complexity on the client's side and saves protocol overhead for transactions (TCP header, etc.).
If performance analysis shows that the call is too slow because it requests too much data (user experience suffers) then I would go with your 2nd solution.
Summed up I would start with 1st approach. Optimize (go with more complex solution) when it's necessary.
I'd prefer the two calls because of the reusability. Maybe one day you need add a third list of users for one case and then you'd need to change the method if you would only use one method. But then there may be other use cases which only required the two lists but not the three, so you would need to change code there as well. Also you would need to change all your testing methods. If your project gets bigger this makes your project hard to update or fix. Also all the modifications increase the chances of introducing new bugs as well.
Seeing the methods callable by the frontend of the backend like an interface helps.
In general an interface should be open for extension but closed on what the methods return and require. As otherwise a slight modification leads to various more modifications.

decorator pattern to allow different behavior of a model

I was wondering whether the use of a decorator pattern is good in case I want my model ("M part" of MVC) to raise Exceptions depending on their origin. I explain myself.
I have a class called Game which is a part of the Model. I have two Views : a GUI and a command line. I want my model to raise an Exception for command line view when the user enters a character instead of a number (for example). Of course I don't want this Exception to be handled by the model as it "belongs" to the command line and not to the Model itself.
To encapsulate those two different behaviors, I plan to decorate the Game class with two classes : CommandLineGame and GUIGame which have only one attribute : Game and handle their own kind of Exception. Is it a good idea ? Is there a better one ? The problem of such a solution is that every model class raising Exception depending on its origin has to be decorated...
What you are describing in the example is "input validation". Strictly speaking*, this belongs in the Controller ("C Part") of MVC.
The separation of concerns for MVC decomposes as follows:
View is there to 1) present a UI for the user to evaluate the state of the program (Also, what your program looks like visually) and 2) to receive the user's expression of intent (receive raw instructions on what they may want to do)
Controller is the actual interpreter of these "actions" or "intentions" from the user. It decides what it means for a user to click a particular button and what to call in your model. It decides whether a particular input actually makes sense given context from the UI (and in some case from the model).
Model should be View/Controller agnostic (Meaning the model should have no knowledge of the View/Controller). It should only be about the internal representation of what you are trying to "model". The advantage of doing it this way: you can have many different UIs, or change your existing UIs without affecting the model.
Overall, the idea is to lower coupling and increase cohesion.
I hope that makes sense =)
Depending on the language / framework, the lines between MVC components get blurred a bit. Some idioms will lump most of Controller into the View, but the encapsulation of logic should stay relatively similar.
*In practice, for defensive programming, input validation is done twice for mutual suspicion: they are broken down into client-side mediation and server-side mediation:
In this case, the Model part should handle the "server-side" mediation: it should check that the arguments passed to its functions actually make sense before proceeding.
Similarly, the Controller/View part should check the input as part of "client-side" mediation, so that it can warn the user right away, without passing it back to the model, and then eventually back to the view.
It will keep your code very clean, something i like a lot from an academic perspective.
On the other hand do you need to introduce this kind of design complexity for a simple problem like this?
So, if you need the code to be clean... GO for it.

GUI patterns in Java/GWT - general approach

I'm helping to build a GWT application for a client and rewrote most of the stuff to work better, shorter code, faster, etc. However in all the GUI application I've worked on (not so many really) there comes a flexing point where you just have to put a lot of rules and move logic from the listeners to some common mediator. Then some times this could get an ugly mess so you whatever small think you need to do in the listener.
Let's take an example:
form with 10-20 fields
two exclusive radio control about half of the state of the other fields (enabling, validation, input limits)
three exclusive radio controls control again almost the same fields, but in a different way (affecting calculations, enabling); they are also controlled by the above
4 or so number fields are validated on the fly depending on the previous selections and some real-time data object; they can have upper/lower limits, be enabled/disabled
one drop-down box controls the next 6 or so controls - displaying/hiding them, modifying validators
some checkboxes (shown by the above combo) activate some input fields and also determine their validation algorithm
While everything is up an running, without known bugs, there are a few coding gotchas that really bother me:
code is spread among listeners and some mediator methods.
loading the form with some preset values presents its own challenges: like data objects that might be available or not, data objects that might alter their state and subsequent field behaviour
some fields are having a default value set and this should not be overwritten by automatic filling, but if the data objects are not there (yet) then they will need to be filled eventually when the later become available
form cannot be submitted if any of the fields are not validated
My approach:
identify which fields share a common afair and move code into one place
each radio group shares a single listener implementation between its radios
default form filling is deferred until the live data is available (as much as possible) and as a result it gets called multiple times
each action has a call to a common validator method
the validator runs through all the fields in the form, calls their validators (which highlight all errors) and returns a single boolean
each relevant keypress or mouse action, data change it gets deferred to be called after 250ms from the last call; this means first call just places the validator as a delayed action, subsequent calls reset the timer
Ok, it doesn't make any sense to dwelve into more details but I'm more upset about the fact that there is no clear separation between visual actions (enabling), data actions (setting form field values), field listeners, retrieving form values and live data listeners.
What would be a good approach/pattern (next time maybe) to make sure that MVC get separated and lends itself better to maintenance? I know this is not a typical question but I've read every documentation I could get my hands on and still did not find some helpful answer.
I'd move closer towards MVP than MVC. It's clearly the way Google intends to go, so adopting it will probably mean that you're able to go with the flow rather than fight the current.
How does this affect you? Well, I believe you should accept that a tidier implementation may involve more code: not the 'shorter code' you were hoping for. But, if it's logically structured, efficient code the Google compiler should be able to trim lots out in the compiler optimisation phase.
So, move as much of the logic as you can into the model layer. Test this thoroughly, and verify that the correct level of page reset/tidying happens (all of this can be done with plain JUnit, without any UI). Next, use your Presenter (Activity) to tie the View to the Model: handling the interactions, populating the fields, etc.
you can divide a Huge class in different classes bu dividing the GUI in different JPanels. All the panels are implemented in different classes extending JPanel. Guess that would help you.

Understanding this architecture

I have inherited a massive system from my predecessor and I am beginning to understand how it works but I cant fathom why.
It's in java and uses interfaces which, should add an extra layer, but they add 5 or 6.
Here's how it goes when the user interface button is pressed and that calls a function which looks like this
foo.create(stuff...)
{
bar.create;
}
bar.create is exactly the same except it calls foobar.creat and that in turn calls barfoo.create. this goes on through 9 classes before it finds a function that accessed the database.
as far as I know each extra function call incurs more performance cost so this seems stupid to me.
also in the foo.create all the variables are error checked, this makes sense but in every other call the error checks happen again, it looks like cut and paste code.
This seems like madness as once the variables are checked once they should not need to be re checked as this is just wastinh processor cycles in my opinion.
This is my first project using java and interfaces so im just confused as to whats going on.
can anyone explain why the system was designed like this, what benefits/drawbacks it has and what I can do to improve it if it is bad ?
Thank you.
I suggest you look at design patterns, and see if they are being used in the project. Search for words like factory and abstract factory initially. Only then will the intentions of the previous developer be understood correctly.
Also, in general, unless you are running on a resource constrained device, don't worry about the cost of an extra call or level of indirection. If it helps your design, makes it easier to understand or open to extension, then the extra calls are worth making.
However, if there is copy-paste in the code, then that is not a good sign, and the developer probably did not know what he was doing.
It is very hard to understand what exactly is done in your software. Maybe it even makes sense. But I've seen couple of projects done by some "design pattern maniacs". It looked like they wanted to demonstrate their knowledge of all sorts of delegates, indirections, etc. Maybe it is your case.
I cannot comment on the architecture without carefully examining it, but generally speaking separation of services across different layers is a good idea. That way if you change implementation of one service, other service remains unchanged. However this will be true only if there is loose coupling between different layers.
In addition, it is generally the norm that each service handles exceptions that specifically pertains to the kind of service it provides leaving the rest to others. This also allows us to reduce the coupling between service layers.

Differences between 2 objects with Java reflection : how?

For an audit log, i need to know the differences between 2 objects.
Those objets may contains others objets, list, set of objects and so the differences needed maybe recursive if desired.
Is there a api using reflection (or other) already for that ?
Thanks in advance.
Regards
It's a pretty daunting problem to try and solve generically. You might consider pairing a Visitor pattern, which allows you to add functionality to a graph of objects, with a Chain of Responsibility pattern, which allows you to break separate the responsibility for executing a task out into multiple objects and then dynamically route requests to the right handler.
If you did this, you would be able to generate simple, specific differentiation logic on a per-type basis without having a single, massive class that handles all of your differentiation tasks. It would also be easy to add handlers to the tree.
The best part is that you can still have a link in your Chain of Responsibility for "flat" objects (objects that are not collections and basically only have propeties), which is where reflection would help you the most anyway. If you "catch-all" case uses simple reflection-based comparison and your "special" cases handle things like lists, dictionaries, and sets, then you will have a flexible, maintainable, inexpensive solution.
For more info:
http://www.netobjectives.com/PatternRepository/index.php?title=TheChainOfResponsibilityPattern
http://www.netobjectives.com/PatternRepository/index.php?title=TheVisitorPattern
I have written a framework that does exactly what you were looking for. It generates a graph from any kind of object, no matter how deeply nested it is and allows you to traverse the changes with visitors. I have already done things like change logs generation, automatic merging and change visualization with it and so far it hasn't let me down.
I guess I'm a few years too late to help in your specific case, but for the sake of completion, here's the link to the project: https://github.com/SQiShER/java-object-diff

Categories