Tuesday, June 6, 2006

7-Layer Dip

Java architects are insecure. They make the big decisions and try to make as many software layers as possible to maximize complexity. Somehow when entrusted with designing reusable software that is to be used by tens of Java programmers, software architects feel the need to make lots and lots of decisions, in order to confuse the poor souls who really just want to solve the problem and go home for a quiet evening of beer and Tivo. That's job security, it makes the Java architect indispensible to the project, calming their insecurities. It makes for large system that have layers and layer of code.

I call this 7-layer-dip architecture. Its is an n-tier idea gone terribly wrong, putting layer after layer of architectural bloat on the code until its nearly impossible to figure out where to make changes to add something like a new field on my object & web page. Its like a 7-layer dip, lots layers and time consuming process to create a tasty appetizer.

In a 7-layer dip - its all about the beans. If you take away the beans, you have a 6-layer dip, right? No, you do not. Instead you have some lame-o salad. Without the beans, you have something that's no longer Mexican, you have to dump out your margarita! The Fiesta is OVER! The other 6 layers are important, for without them its just beans and who wants that, its no longer fun without the other layers. Do I need 7? No. I think 4 layers is still pretty tasty, but we're enamored with the number 7, so we make up a few more.

Analgoy-stretching time: In Java apps its also about the beans- the Java beans, the POJOs, the model classes - the simplest form of code, the useful stuff. Without the beans you have no application, just empty framework stuff, no fun, no margarita. But then some Java architects like to wrap these beans in 7 layers of tomatoes and lettuce and cheese and sour cream and tortillas because they think its necessary to keep the party going. This is where the party goes wrong - Java beans do not need 6 more layers of wrappers and EJBs and services and business delegates and data accessors and views and actions. These layers do not add to the fun of writing software. Instead, they serve to alienate developers from the important parts - the beans, the app, ...the user. Developers then try to make themselves look smart by jumping on the buzzword bandwagon. I should never hear a developer utter a phrase like this in front of a user, "well, I can just make the action return a new implementation from the business delegate factory". Perhaps Java developers boast of bloat-buzzwords so they can raise their pay, but if the users are smart, they will just be annoyed and they'll hire that PHP script kiddie from the basement next door.

In the late 90s we all let Sun talk us into n-tier machines with Entity Beans, CORBA, and SNA spread out in 5 times zones, so we could write "Enterprise applications!" (and buy some E-class Sun hardware). We took in some good dot-com paychecks and the accountants and managers rode our e-coat-tails to high stock prices. Good for us! In the meantime, 8th graders were selling T-shirts with PHP apps running on old hardware in their basement. And they did it all that by reading "Learn PHP in 7 minutes". Sure, that little PHP app is not ready to handle 8000 hits per minute, but its built to be the right size for selling T-shirts out of a basement, and when he needs to add the baby-tee sizes and the 3XL sizes to the web site, he can do it in a day by recoding some PHP and adding some columns to his MySQL table.

Don't panic, I'm not advocating the destruction of design patterns, I still advocate the use of Factory and MVC and lots of other good designs. But they are simply being overdone. For example, I like to use the Factory pattern if I'm pretty sure I have two different impls to hand out in different situations. A SecurityService is a good example for just about any app, because I have changing needs from development to production. I can write one SecurityService for LDAP and one for reading a password file to authenticate users. I use a SecurityFactory to return the correct service, so I can change it out for test vs. production by changing a simple config file. Great. There, I used a factory pattern in a good way to swap out two different pieces of code seamlessly. But I don't need a Factory for every bean in my system. When am I really going to need two different impls for a Book object? I mean if the web site sells Books, there's probably only one way to sell books, do I need a Factory to pass out two different classes of Book? Almost never. But this kind of knee-jerk over-architecture decision is everywhere even in closed-source corp IT systems. If, by chance, I invent another impl for a book, I can slam a BookFactory in later while I'm putting in the new BookImpl - easy stuff (even easier, use Spring). But making a BookFactory in an application is usually just obnoxious. The only reason to do that is to pad your own resume with bloatware knowledge. I know..I know.. you can contrive the need for a PoolingBookFactory and a SimpleBookFactory and a WebServiceEnabledBookFactory. But most of the time you just need a Book - new Book(), its just that simple. Very few cases arise where I need the kind of flexibility a Factory pattern provides, but develoeprs and architects don't even remember the reason for the complex case and they abuse that pattern for a much simpler case like Books just in case they'll need it later.

This kind of over-architecture slows down developers, especially new ones who must learn this annoying bloat-itecture before they can add a new simple property to the Book class like Book.setOprahPickedIt(boolean b).

Why does this happen? What makes this bloat so prevalent? Who promotes these guys to Architect positions and lets them run big software projects? It must all come from the old waterfall addage that big code now is cheap, and change later is costly, RUP uses this principle to justify their brand of $10K tools. That theory then pushes the derivative theory: "why overarchitect later what you could over-architect today?" So IT managers believe a Java architect when he hears "well we need all this code to scale and to be prepared for change", and the checkbook writes a big check for "architecture and design" with zero expectation of a demo or milestone release coming anytime soon. And admittedly, I've jumped onto a project and I drank the kool-aid and gave the architect the benefit of the doubt "certainly there must be a really good reason for all this code...". And I changed piles of code to add a single property to a class. But when I turn to ask a peer whose been grueling with the system for 10 months, that poor coder is hard-pressed to answer the question "why?". This doesn't just happen on old EJB projects, it happens on EJB-less Web projects and thick-client apps too. Reminds me of this old parable: why we do things.
The best things to cure my pain are the Agile warriors and the POJO bigots. Both of these groups have shown me that simple is better and that change is pretty cheap. If you build your code in a simple way first, then strap on some good features one by one carefully, your code doesn't need to blow up into a confusing mess and you'll be agile when the customers change their minds or ask the system to do more. I like the Spring and EJB3 movements for reminding us that simple is good. And I like the Agile movement for the idea that change is inevitable, trust your customers and don't hire a lawyer to write that contract. Now we just need to convince all the decision makers that this is the best way.

Little piece of advice to those architects of bloat. Embrace change, keep thing simple, and read some software articles written in this decade. I recommend theServerSide and the Agile Manifesto .

Jay Meyer

jmeyer@harpoontech.com

No comments: