tags:

views:

98

answers:

4

In my new assignment, I have inherited this legacy chunk, which I had to redesign and refactor. The scope was initially restricted to the Presentation tier, which happened to be the bulkiest of all. During the course of analysis, it was realised that the application was built over a period of time with various modules using different classes to depict the same model.

These models are actually used to bind information into both view and db tier (Code reuse somebody?). The binding logic is a complex routine and was stabilised after multiple rounds of testing. Now I have this dilema of whether to retain these semantically duplicate but syntactically inconsistent models or to start with a clean slate. The second option would mean revamping the whole application and the schedules don't allow for that, but I have a bad inkling. Can you guys share some inside thoughts (pros & cons) and any unforeseen problems I may face in future.

Giving the following analogy which closely reflects the state of affairs.

  1. To start with, there is a user details module, which is more like a getter. The view gets rendered using the TO (transfer object) structure provided for this. Say 'Class UserInfo'
  2. Later a new requirement came up and a provision to edit the details was provided. Whoever coded it decided that they would use a new TO structure and came up with their own 'Class UserEditInfo'. Which is kind of super set of earlier class.
  3. Finally at a different point of time, a new enhancement to keep track of user transactions was made and guess what, a new 'Class UserDetails' was created.

All the above have bindings that map them to external tier and JSP logic, trying to eliminate two of the models would cause repurcussions in the whole Business tier (which is bad). To make things worse, the good old cowboys are nolonger around to help us out. Hope this helps

A: 

There is not much value to be gained from re-writing the whole thing just because the architecture is not ideal. As you noted yourself it WILL be VERY costly.

One approach would be to pick the best implementation of the models and concentrate further development in that model.

If you need to expand some functionality from one of the other models that will be your opportunity to migrate the implementation of the existing feature from the legacy model to your chosen primary model and extend it as required.

Declan Shanaghy
+4  A: 

Ok, well as you mentioned, you cannot start fresh so lets forget that idea.

What I like to do, is to find code that does the same thing (like you bindings modules) and make them implement a new interface of your own design. Like IDataBindingsModule, this interface has common methods that both modules "do" (as you say) the same.

Then remove all instances of the concrete types and use the new IDataBindingsModule interface instead, then once you have done that and made sure that nothing has broken, its simply a matter of replacing the implementations of your new IDataBindingsModule interface with a unified implementation.

This approach only works if the multiple modeuls as they are now really do do the same thing, otherwise this wont work very well.

I hope this is on the right track as to what you were asking, sorry if I miss-understood you.

Mark
I've done a similar refactoriing job, and that was the approach I used as well - extract out the common methods into an interface, then merge the model classes underneath.
Mark Bessey
This is also a GREAT chance to get into the 'Unit' framework for use of dependency injection which works great from an interface based design perspective (or any other DI based framework).
Mark
Whoops, I meant "Unity" sorry, not "Unit"
Mark
+1  A: 

Assuming you have 1 to 1 mapping of the classes in both models, you could try to merge them.

You can do it by taking one of the corresponding classes as base and make the other class inherit from it and from an extracted interface. Next thing is to move all your mapping logic inside the class (ideally inside the property accessors). The new model will still be used through the old interface types, just the concrete implementation will be the same.

This will allow you to cast the same object between the old and the new representations. Gradually you can hunt down the usages of the undesired methods and remove them. This will take a long time, but is less risky than rip and replace.

ddimitrov
A: 

As Mark as detailed, you can implement the Adapter pattern to create a single interface to the disparate object models. This allows to present a unified interface to the presentation layer of the app while preserving what you works on the back end.

In time you can then refactor the pieces that you want to alter while still being able to test you results against the function application.

David Robbins