3

The development team I'm a part of wrote and still maintains a codebase of pure Java spaghetti code. Most of this was implemented before I joined this team.

My background is in Python/Django development and the Django community really emphasizes "pluggability" -- a feature of Django "apps" (modules) which implies mostly "one thing and one thing well", re-useability, loose coupling, and a clean, conscious API. Once the Django team I once worked in started to "get it", we pretty much had zero problems with messy, tightly-coupled masses of monolithic code.

Our practice involved developing Django apps outside of the Django project in which we intended to use the app (a common practice among Django developers, from what I've gathered) Each even lived in a Git repository separate from that of the overall Django project.

Now, we're presented with an opportunity to refactor much of our spaghetti code, and it seems to me that some of what I learned from the Django community should be applied here. In short, I'd like to see our new codebase developed as a series of "pluggable" modules each written under the assumption that it won't have access to other modules (except those on which it should rationally depend). I believe this should do a good job of driving home principles of proper software design to the whole team.

So, what I'm advocating for is to have one separate repository per "feature" we want in our new (Spring) project. Each would have its own, independent build process and the result would be a .jar . We'd also have a repository for project-level things (JSP's, static files, etc) and its build process would produce a .war . The .jars wouldn't be placed inside the .war, but rather be treated as Gradle dependencies (the same way third-party dependencies would be.)

Now I have to sell it to the boss. He's asked for some example of precedent for this plan. Obvious places to look would be open-source projects, but if a project is split across multiple repositories, it's likely to be multiple projects. So, perhaps I'm looking for some sort of suite. Spring itself looks promising as an example, but I haven't been able to find many others.

My questions are (and sorry for the long back-story):

  • Is there any such precedent?
  • What examples are there?
  • Is there any documentation (even just a blog post would be of help) out there advocating anything like this?
  • Any suggestions for implementing this?
  • Is this even a good idea?

Thanks in advance!

Edit: Whether or not to refactor is not in question. We have already decided to make some drastic changes to most of our code -- not primarily for the purpose of "making it cleaner" in fact. My question is about whether our planned project structure is sound and how to justify it to the decision-makers.

AntiMS
  • 337
  • 4
  • 15
  • 3
    Don't refactor, keep supporting the spaghetti stuff ;) Anyone can refactor, spaghetti is for real men only. – peter.petrov May 01 '14 at 18:11
  • Whether or not to refactor is at this point a moot point. It has already been decided. One of our aims with our new project is to remove our dependency on old versions of Struts and convert all code as necessary to instead use Spring. – AntiMS May 01 '14 at 18:25
  • 1
    What this is talking about semantically is **rewriting**. You use the term **refactoring** which is not the same thing as what you are describing. Someone that doesn't understand the semantics has been sold a bridge and is going to be pissed when this fails spectacularly, which is the only way these things ever end. –  May 01 '14 at 18:37
  • Rewriting, then. Would you like me to edit this correction into my original post? Whatever the case, this response is pretty far off topic. Hypothetically if we were not rewriting anything but were instead implementing a new project from scratch, how would you answer? – AntiMS May 01 '14 at 18:43
  • There is no need to have multipl – Peter Niederwieser May 01 '14 at 18:47
  • 1
    *Implementing a new project from scratch* that replaces an existing project is also **rewriting**. Those fail even harder, Google "big rewrite" and read up on that. **Either way this question is mostly off-topic, too broad and too opinionated** which is proved out by the answers, mine included! –  May 01 '14 at 18:48
  • **JSP** ? Instead of 'refactoring/rewriting', design a new system with newer technologies, like **JSF**. And ask yourself, do I really need **Spring** ? –  May 01 '14 at 18:54
  • Thanks everybody for your input. It's been helpful. However, I don't really see this question producing any better responses than it has so far, even if heavily edited. So, I'll just plan to simply allow it to be closed in five days. Please feel free to close it sooner if you can and would like to. – AntiMS May 01 '14 at 20:11
  • 1
    JSF is not the answer, the only people that push JSF are consultants that want to lock their clients into an expensive and complex solution that they will need constant help with, oh how I wish I could downvote comments! –  May 01 '14 at 20:53
  • This question is totally inappropriate to Stack Overflow, but I feel sad for the OP. It is a tough situation to be in and there are many possible tips on how to do that (although I doubt the OP is experienced enough to even understand them). Maybe is it a question for http://programmers.stackexchange.com? – brandizzi May 02 '14 at 14:58

5 Answers5

3

The following issues are more important that where to put code on the disk or in an artifact:

If you don't understand that, you have already failed.

What you describe is not refactoring, it is rewriting using a more palatable name:

Unless you have 100% code covered in unit tests already; someone(s) are going to get fired over this when ( not if ) this effort fails spectacularly, probably multiple times!

Even with awesome unit tests, someone is going to miss something and someone is going to take the fall when it finally gets discovered in production, usually after months of silently corrupting data.

Semantics are Important:

Removing Struts and replacing with Spring is not refactoring is rewriting by definition. Refactoring would be moving from Struts 1.1 to 2.0, replacing Struts means replacing all the Struts code with something else, by definition that is rewriting not refactoring.

Working Software comes in many disguises:

The business always thinks what they have is working.

Miss a deadline, introduce a bug no matter how minor, lose a feature no matter how minor, mis-interpret an undocumented process and change something no matter how minor or even for the better. They are just looking for any problems weakness or potential trouble to spread FUD and make sure your effort is a failure, at least most of the time.

All these things will cost you and your team political capital, someone will take the fall for these things, no matter how innocent or merit-less the perceived failures are!

Projected outcome:

Most likely you and/or other "non-Java" developers and not the core Java people that created this working system that you "non-Java" people refactored ( code word for rewrite in this case ) and delivered on time broken and incomplete or didn't deliver on time or didn't deliver at all.

Community
  • 1
  • 1
  • 3
    they mentioned `struts` that means overly complex and hopelessly entangled! Both are my specialty at dealing with after the fact. Removing struts is **NOT** refactoring, it is **rewriting**, completely different tasks and possiblities of outcomes for success. –  May 01 '14 at 18:32
  • in that case deleting my comment:P since I hardly use java at all (only when absolutely necessary) – Joran Beasley May 01 '14 at 18:33
  • I'm not sure I even understand your answer. Someone is going to get fired over _what_ when _what_ fails spectacularly? Is the plan to refactor (which, again, is not in question) going to fail spectacularly? The particular proposed repository structure we're proposing? Or are you saying that the simple act of modifying much of the code will introduce bugs? – AntiMS May 01 '14 at 18:35
  • Also, the "core Java people" you mention (by their own admission) entered the original project with little Java and/or programming experience or training and the "working system" has a pretty embarrassingly dismal uptime record. Also, the "working system" has not been "refactored" (or even touched to any significant extent, really) by any "non-Java" developers (who, by the way, have similar amount of Java experience as the "core Java people") yet. – AntiMS May 01 '14 at 18:39
  • to the business it is **working** by definition right now, even the smallest hiccup ( subtle bug, perceived performance issues, missed deadline ) is going to start a negative trend for the team that will snowball into disaster for someone, and it won't be management, it never is! –  May 01 '14 at 18:42
  • Thank you for your input. Point taken. We shouldn't be rewriting any code. Thanks, really. But your input is way off topic. – AntiMS May 01 '14 at 18:48
  • Point not taken, you are worrying about the wrong thing. –  May 01 '14 at 20:52
1

I think it's possible to find examples of good and bad implementation in both Java and Python.

Spring is indeed a good place to start. It emphasizes good layering, designing to interfaces, etc. I'd recommend it highly.

Spring's layering is "horizontal". If "module" means "business functionality" to you, then multiple modules will be present in a given layer.

Plugable suggests a more vertical approach.

Maybe another way to attack it would be to decompose the system into a set of independent REST web services. Decouple the functionality from the interface completely. That way the services can be shared by web, mobile, or any other client that comes along.

This will require strict isolation of services and ownership of data sources. A single web service will own/manage a swath of data.

I'd recommend looking at Michael Feathers' book "Working Effectively With Legacy Code". It's ten years old, but still highly regarded on Amazon.

One thing I like about the REST web services approach is you can isolate features and do them as time and budget permit. Create and test a service, let clients exercise it, move on to the rest. If things aren't too coupled you can march through the app that way.

duffymo
  • 305,152
  • 44
  • 369
  • 561
0

Refactoring entire application is not an easy task, specially if the code is hard-wired as you have described. If Pluggablity is an important target, I would recommend Grails/Groovy.

If you can somehow identify view, controller and business logic, or much better services. You might be able to reuse some existing codes. The good thing about grails/groovy is that you are able to incorporate JSP/JAVA with GSP/GROOVY.

Again, this is really hard to sell and grails is probably a good framework to ease the refactoring pain.

Armaiti
  • 766
  • 3
  • 11
  • Blast. All of these answers imply I haven't properly communicated the point of my question... I'd better edit it. – AntiMS May 01 '14 at 18:27
0

I would recommend watching "Four Strategies for Dealing with Legacy Code" by Eric Evans, the originator of Domain-Driven Design: http://dddcommunity.org/library/evans_2011_2/

It may not entirely answer your question but it offers arguments and strategies that might help with your endeavour.

Dennis Traub
  • 50,557
  • 7
  • 93
  • 108
0

Every component is in its own jar, but the jars are not contained in the war ? How should that work ? Even third party libs are included in the war. Except for those that are provided by the container. Regarding the jsp stuff: Can I serve JSPs from inside a JAR in lib, or is there a workaround?

Community
  • 1
  • 1
rogergl
  • 3,501
  • 2
  • 30
  • 49