Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Is there an anti pattern that describes a historically grown software system where multiple developers just added new features to the system but no one really kept an eye on the overall architecture nor were refactorings ever done?

I think this happens when management/customer asks for new feature constantly and no one ever refactors anything but just adds on to what other developers haven done before.

A reason could also be that the developer is just overwhelmed with the software system and does not really understand how it currently works and then just adds/glues his code at the very end (instead of refactoring the code and changing it.)

So over time it's getting harder and harder to maintain the system.

(I wonder if there are pictures for these kind of anti pattern to make this more clear to none programming folks - like a car that was built by just adding more and more features without thinking of the overall design. Like someone has the need to tow trailers while riding backwards and then an engineer just welds a tow bar to the front of the car. Job done. But now the cowl doesn't open anymore.)

share|improve this question

closed as primarily opinion-based by gnat, MichaelT, Kilian Foth, Michael Kohne, Bart van Ingen Schenau Mar 19 at 12:37

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise.If this question can be reworded to fit the rules in the help center, please edit the question.

Non-programmers probably aren't going to understand antipatterns, being, y'know, programming terms. I think what you want is an analogy... –  Izkata Mar 14 at 21:46
Besides, an anti-pattern has to be a design pattern ... that you should not copy. And what you are describing is really a software management syndrome rather than design pattern. –  Stephen C Mar 15 at 8:35
It's called "feature-creep" or "scope creep." –  Robert Harvey Mar 17 at 18:50

2 Answers 2

up vote 32 down vote accepted

You refer to Technical Debt.

We all accrue technical debt in the products we develop over time, refactoring is one of the very common and effective ways of reducing this technical debt, though many companies never pay down their technical debt. These companies tend to find their software extremely unstable years down the road, and the technical debt becomes so gruesome that you can't pay it down incrementally because it would take too long to pay it down that way.

Technical debt has the term because it follows the same behaviours of debt. You get the debt, and as long as you continue spending (creating features) and not paying down that debt, it'll only grow. Much like debt, when it get's too large you get to points where you may wish to shed it entirely with dangerous tasks like full-out rewrites. Also like real debt, as it accrues to a certain point, it hinders your ability to spend (creating features) altogether.

Just to throw another term in the mix, cohesion refers to how well a system, micro to the line level, or macro to the system level, fits together. A highly cohesive system will have all of it's pieces fit together very well and look like one engineer wrote all of it. Your reference above to somebody just gluing their code to the end would be violating the cohesion of that system.

Managing Technical Debt

There's a lot of ways to manage technical debt, though like real debt the best approach is to pay it down frequently. Unfortunately like real debt it's occasionally a better idea to accrue more for a short period, where for instance time to market for a feature may double or triple your revenue. The tricky part is weighing these competing priorities as well as identifying when the debts ROI isn't worth it for the given feature vs. when it is.

So sometimes it is worth it to accrue the debt for a short period, but that's rarely the case, and as with all debt, the shorter the period the better. So eventually (preferably quickly) after you accrue technical debt, you have to pay it down, these are common approaches:

  • Refactoring
    • This allows you to take bits of code that were only realized to be misplaced partway through or after implementation was complete, and put them in their correct place (or a more correct one anyway).
  • Rewrite
    • This is like a bankruptcy, it wipes the slate clean, but you start with nothing and have every opportunity to make the same mistakes, or even bigger ones. High risk high reward approach to technical debt, but sometimes it's your only option. Though that's more rarely the case than many will tell you.
  • Architecture Overview
    • This is more of an active technical debt pay-down approach, this is done by having someone with authority over the technical details to halt an implementation regardless of project plans and schedules to ensure it accrues less technical debt.
  • Code Freeze
    • Freezing the code of changes can allow you breathing room where your debt doesn't go up or down, this gives you time to plan your approach to reducing the technical debt with hopes of having the highest ROI on your approach.
  • Modularization
    • This is like a tier-2 approach only available when you employ either Architecture Overview to have a modular system already, or Refactoring to move towards one. When you have a modular system, you can then pay down debt in whole pieces of the system in an isolated way. This allows you to do partial re-writes, partial refactoring, as well as minimizing the rate technical debt accrues because the isolation keeps the debt only in those areas where the features went in, as opposed to spread around the system.
  • Automated Tests
    • Automated testing can aid in managing your technical debt because they can help you identify trouble spots in the system, hopefully before the debt in those areas has grown very large, but even after the fact they can still make engineers aware of those dangerous areas they may not have already realized. Furthermore, once you've got automated tests, you can more freely refactor things without concern for breaking too much. Not because devs won't break things, but because they'll find out when they do break things, relying on manual testers in highly indebted systems tends to have a poor track record for finding issues.
share|improve this answer
Good answer, I was just going to call it software development, but you are of course right in calling it technical debt. :-) –  Encaitar Mar 14 at 17:33
Ha ha. Yeah, I guess this is a pretty common problem. But I like technical dept and I think it fits pretty well. –  Jens Mar 14 at 17:57
Couldn't an original design create technical debt when fixing bugs without the result of new features continuously being added? –  JeffO Mar 14 at 18:44
@JeffO yes, the issue is more an artifact of churn than creeping featuritis, though one causes the other. I'll correct when I'm back at a computer, thanks for the comment –  Jimmy Hoffa Mar 14 at 19:03
"relying on manual testers in highly indebted systems tends to have a poor track record for finding issues." - very believable, but do you have a source? –  Aaron Hall Mar 14 at 20:52

Your description fits Foote and Yoder's Big Ball of Mud:

Over the last several years, a number of authors... have presented patterns that characterize high-level software architectures... In an ideal world, every system would be an exemplar of one or more such high-level patterns. Yet, this is not so. The architecture that actually predominates in practice has yet to be discussed: the BIG BALL OF MUD.

A BIG BALL OF MUD is haphazardly structured, sprawling, sloppy, duct-tape and bailing wire, spaghetti code jungle. We’ve all seen them. These systems show unmistakable signs of unregulated growth, and repeated, expedient repair. Information is shared promiscuously among distant elements of the system, often to the point where nearly all the important information becomes global or duplicated. The overall structure of the system may never have been well defined. If it was, it may have eroded beyond recognition. Programmers with a shred of architectural sensibility shun these quagmires. Only those who are unconcerned about architecture, and, perhaps, are comfortable with the inertia of the day-to-day chore of patching the holes in these failing dikes, are content to work on such systems...

Why does a system become a BIG BALL OF MUD? Sometimes, big, ugly systems emerge from THROWAWAY CODE. THROWAWAY CODE is quick-and-dirty code that was intended to be used only once and then discarded. However, such code often takes on a life of its own, despite casual structure and poor or non-existent documentation. It works, so why fix it? When a related problem arises, the quickest way to address it might be to expediently modify this working code, rather than design a proper, general program from the ground up. Over time, a simple throwaway program begets a BIG BALL OF MUD.

Even systems with well-defined architectures are prone to structural erosion. The relentless onslaught of changing requirements that any successful system attracts can gradually undermine its structure. Systems that were once tidy become overgrown as PIECEMEAL GROWTH gradually allows elements of the system to sprawl in an uncontrolled fashion.

If such sprawl continues unabated, the structure of the system can become so badly compromised that it must be abandoned. As with a decaying neighborhood, a downward spiral ensues. Since the system becomes harder and harder to understand, maintenance becomes more expensive, and more difficult. Good programmers refuse to work there. Investors withdraw their capital. And yet, as with neighborhoods, there are ways to avoid, and even reverse, this sort of decline. As with anything else in the universe, counteracting entropic forces requires an investment of energy. Software gentrification is no exception. The way to arrest entropy in software is to refactor it. A sustained commitment to refactoring can keep a system from subsiding into a BIG BALL OF MUD...

  • ...One of mud's most effective enemies is sunshine. Subjecting convoluted code to scrutiny arrow can set the stage for its refactoring, repair, and rehabilitation. Code reviews are one mechanism one can use to expose code to daylight.


share|improve this answer
I came across "big ball of mud" but with a slightly different explanation. Now that I read your answer and also read what the wikipedia article on "big ball of mud" says about it, this actually fits pretty good. (Though I think the term itself might not be very charming while trying to convince management to stop implementing new features and do a refactoring.) –  Jens Mar 14 at 18:04
@Jens per my reading, your didn't ask about how to convince management to invest into avoiding a mess (if it did, I wouldn't even mention BBoM, since it would be irrelevant / the answer would be technical debt). What I read though was: "anti pattern that describes a historically grown software system where multiple developers just added new features to the system but no one really kept an eye on the overall architecture nor were refactorings ever done" - that's BBoM –  gnat Mar 14 at 18:09
You are right. My question was about getting a term to what I had in mind. Convincing management is a second thing out of the question's scope (but has been on my mind). But as for the question your answer fits perfectly (upvoted it already). –  Jens Mar 14 at 18:31
Code review - Great call! Will add to the managing technical debt list above when I'm back at a computer. This should be accepted as the answer, I forgot this term off hand. –  Jimmy Hoffa Mar 14 at 18:55
@Jens read the BBoM article - at the end are suggestions for resolution and repair. –  gbjbaanb Mar 14 at 19:28

Not the answer you're looking for? Browse other questions tagged or ask your own question.