Tuesday, October 16, 2007

Deconstructing Frankenstein


One of my favorite things I do in any architecture or design course I teach is to discuss AntiPatterns—design ideas hatched with good intentions but that prove problematic over time. We’ve all seen examples of software done badly. The purpose of an AntiPattern is to document a bad solution to a common problem, explain how people can slide into an AntiPattern, and mention ways to remedy it. The point isn’t as much to say “don’t do this” as it is to say “you probably already have this problem, you just might not have a name for it. And here is how you might’ve gotten there, here is what you might do to prevent this happening in the future, and some things you might do to fix up your design.”

A Boat Anchor is a piece of software or hardware that serves no useful purpose on the current project. Often, the BoatAnchor is a costly acquisition, which makes the purchase even more ironic. A Lava Flow is when unused blobs of code are hanging around in a system. It is characterized by the lava-like “flows” of previous developmental versions strewn about the code landscape, but now hardened into a basalt-like, immovable, generally useless mass of code (perhaps commented out, perhaps not) which no one can remember much if anything about.

Last week students at my class were incredibly inventive—they weren’t content to limit their discussion to examples of AntiPatterns that I mentioned. The new AntiPattern names are so good I want to share some of them. The first was the Frankenstein AntiPattern. It came about because “too many cooks were watching the pot.” Everyone wanted to contribute so they did, just not in any organized fashion. As requirements kept rolling in, people kept adding functionality—in a disjointed, haphazard fashion. Oh, you want two eyes? OK. And a body. That sounds good. You didn’t say you need toes. Hm. OK, we’ll bolt some on. How many do you need? Where should they go? Everybody contributed, design coherence wasn’t a goal, and the implementation just kept rolling in requirements.

One might say that good disciplined designers should’ve detected this emerging porblem and prevented it from happening. Well, projects get hectic and sometimes things slide. But what’s nice about this story is that it has a happy ending. Frankenstein was banished after a diligent designer who couldn’t with a clear conscience keep bolting on stuff and make it work said “Enough!” and worked to untangle this mess. He employed several strategies. One was refusing to take code directly from marketing—and to accept requirements and functionality via pseudo code instead of “patches”.

Another AntiPattern that was brought up was Rocky Road. It’s similar to the Lava Flow, but includes overloaded data fields and cobbled together or interpreted data fields in the mix. Not only is there dead code to stub your toes on, but there’s complicated data with overloaded, tangled encodings, too. The intentions were good—keep using the same schema but add more functionality to the software and keep encoding data in complex ways because heaven knows the data can't be redesigned. But over time this system became extremely difficult to work with. The code was complex in that it had to decode and vary functionality based on complex interpretations of the data, and the data fields grew more complex and entangled in support of new functionally. Now what’s great about this AntiPattern name is that “Rocky Road” is an ice cream flavor as well as a travel hazard. What might start out as a sweet, quick fix, can over time turn into an unnavigable development landscape. I’ve seen this situation at other companies I’ve worked at… and there is no quick fix. Someone or several people have to take the time to analyze the code and the data implications and to propose modest “safe” and agreed upon modifications. These repairs don't usually smooth out all the bumps they keep the system from totally becoming unworkable. Usually there has to be a compelling reason to make deep and significant changes (think Y2K or migration to a new database technology).

Sometimes discussing AntiPatterns can be depressing. Especially when people work in places where painful examples are in abundance, and little opportunity or incentive exists to improve things. I like hearing stories where people have been able to repair design problems and improve how systems function. Even better when these efforts are supported and encouraged by informed management. If you have any AntiPattern remediation successes, I’d love to hear about them.

5 Comments:

Blogger Dan said...

I LOVE the idea of AntiPatterns - very useful concept! I was very fortunate to work with some software developers recently who knew what they were doing and were able to avoid these AntiPatterns, even when the customers (like me) tried to push in that direction.

As for addressing these pitfalls, I do have some ideas. Specifically, I think my Simplicity Cycle book can help people address/mitigate/avoid them, by focusing on goodness instead of complexity. It's a free download at http://www.lulu.com/content/877467

4:34 AM  
Blogger Jonathan said...

I do have some Antipattern examples, however I'd rather mention one more item which is unfortunately depressing and bears taking note of.

I see a trend in business lately, especially big businesses, where projects are done in phases. Instead of sticking with a design process and trying to fix the bugs within it, executives get concerned that the problem is within the development methodology, and discount what should have been done at the beginning of the project which is adequate planning. On a recent proejct I've worked on the design wasn't properly thought out, planned for and it was never come back to for revision (or to just plain sell to the client that we need to do more planning for Phase 2 to make it more efficient). This created the horrible situation where the decision was made after an assessment of development methodologies to implement a restructuring and redesign around a new methodology, sort of like going from XP to SDLC. The problem here is that we still have to continue on with XP for at least another phase and we dont get to SDLC at best until the middle of the 2nd or the beginning of the 3rd. I full expect to adopt a brand new one when SDLC fails.

Why? Because nobody will have done the proper prep to get it started the right way, with a proper front end assessment. To me, that's the real crime, and all the Anti-Patterns in the world won't get you there if you don't leave the time for thought and proper planning on the front end.

That's how I see it anyway. Good article there Rebecca, sorry to bring along a downer, but I think it has to be said.

8:33 AM  
Blogger Unknown said...

Another prevelant anti-pattern is Persistence Oriented Software development (no acronym pun intended!). Hibernate/Spring is warping so many object models and implementations nowadays; modeling is entity-focused with controller-based 'Service' classes implementing largely procedural logic. It's a constant uphill battle to convince people to implement good OO designs, regardless of framework constraints.

I've read your books several times. Another I've found to be very good is Object Design Heuristics by Arthur Riel. Good design books can reveal additional information with each reading. Do you have recommendations for other good design books and/or authors, or perhaps a 'readers choice' list from those mentioned in Object Design?

3:41 PM  
Blogger Rebecca Wirfs-Brock said...

I find it interesting Paul's mentioning of the persistence-oriented software development anti-pattern. I must admit I've seen that one, too...and then the goal I might have of adding any behavior to a domain object becomes less acceptable. First off because these are persistent objects, and second because it might interfere with persistence mechanisms...to counteract that type of thinking, I recommend people take a look at Eric Evans' Domain Driven Design approaches...but then the issue becomes one of melding DDD constructs with Hibernate/Spring constructs.

I highly recommend Evans' book for people serious about domain models and preserving a strong link between subject matter experts' views and working code.

9:08 AM  
Anonymous Anonymous said...

I am struggling at the moment the "gypsy wagon" antipattern.
But normally only at the method level.
To me it seems there is a conflict between responsibility driven design and the need to separate objects into the traditional n-tiers. Especially with asp.net data-bound objects on the UI. you end up with a method calling 2 or 3 gypsy wagons to get to the real method n tiers below because that is where the responsibility lies.
It seems to me its better to 'break' the tiers than create this unnecessary coupling between objects.
The designer agrees that it is dirty but feels its better to maintain the tier separation. Is there such a thing as 'tier responsibility' anyway??

6:24 AM  

Post a Comment

Subscribe to Post Comments [Atom]

<< Home