Avoid useless layers: Let each pattern earn its way into your architecture.
The architect in me just loves building solutions that require a healthy dose of layering. There's nothing more fun than walking through an architecture diagram that's loaded with boxes upon boxes of well-defined layers, each with its own role and each with its own clever acronym.
If you're into architecture at all, you're likely to experience this same dynamic. We all want to feel like we're building something that will be the most reliable, distributable, scalable, extensible solution one could possibly imagine. Words like "pluggable," "de-coupled," and "boundary" must flow off our tongues with regularity. Let's face it, most of us live for generality, and architecture gives us a natural vehicle to show off and express this generality.
Of course, while architects were busy assembling their masterpieces, the industry was busy refining and formalizing these concepts as architectural patterns. Much like the Gang of Four patterns (see the StickyNotes for a reference), these patterns brought a real focus and clarity to the architectural concepts we had been building for years. Having official names attached to these concepts gave us all a real sense of comfort. It's almost a form of validation that tells us what we're doing must be right.
If you've ever popped open any of the books on architecture patterns, you've likely marveled at what a fantastic job the authors do describing the blueprint for good architecture. These books contain pattern upon pattern that collectively cover all the major concepts you might confront when architecting a system.
For some, these books and these patterns have actually become their de facto standard for architecture. Some architects and designers flock to these concepts as if they have found the Holy Grail of architecture. These patterns are treated with a kind of reverence that I've rarely seen in the world of architecture. I imagine there's some architect out there with a blown-up poster of Martin Fowler tacked to his wall.
On the bright side, this phenomenon isn't exactly a bad thing. The concepts that are called out in today's enterprise architecture books are built upon sound techniques that have been leveraged for years, and applying them in your solutions is usually a good idea. At the same time, I've watched architects and designers apply these patterns, and I've observed a few tendencies that trouble me.
One specific problem I've noticed is what I call the "Copperfield Pattern." This pattern is triggered by the combination of a handful of well-written architecture pattern books, a poorly defined set of architecture requirements, a strong desire for layering, and a general need to feel like you're doing something right. These factors all conspire to induce well-meaning architects and designers to closely mimic the full suite of architecture patterns without considering how or if those patterns are appropriate for their solutions. Somehow, the illusion of doing the right thing seems to be enough.
Obviously, doing anything blindly can't be a good idea. Still, it happens. In fact, at one site I found a handful of architects who somehow felt compelled to directly lift and leverage almost every pattern they could find. It was as if the system's architects were being paid by the pattern. Every tier of the application required some set of patterns.
The result was fairly impressive on paper. The path from the client to the database passed through pattern upon pattern, each with its own distinct role and purpose. With a single click, the client could pass through an Application Controller, to a Business Delegate, to a Session Façade, to an Application Service, to an Enterprise Service, to a Data Access Object, to the database. Sprinkled throughout this architecture were various references to Service Locators, Service Factories, Value List Handlers, and Transfer Objects.
While it was clear that this particular architecture contained a veritable smorgasbord of patterns, that didn't immediately raise any red flags for me. To the naked eye, there was nothing inherently wrong with including these specific patterns. In fact, there are many solutions that can easily justify the use of each and every one of these patterns.
The real problems with this architecture didn't actually surface until designers and developers started creating the classes that were going to participate in this architecture. No matter how hard they tried, the designers felt as though most of the layers between the client and the database simply weren't adding value. These layers seemed to represent nothing more than glorified pass through mechanisms. This wasn't the universal case, but it was showing up on a disturbingly regular basis. As a result, a change at one layer tended to trickle through the entire architecture. This, of course, is one sure smell that something's wrong with your architecture.
So, how could this dynamic have been avoided? After all, the architecture was certainly leveraging a set of proven patterns with well-intended roles. At the conceptual level, those patterns seemed to be a good fit for the solution's requirements. The truth is that it's human nature to take this sort of formulaic approach to architecture. You see something that seems like it's going to add value, and you immediately incorporate it into your vision.
To overcome this, you need to be more willing to bite off only what you know is needed, and be prepared to let your architecture continually evolve. In this model, you would take more of a "show me" approach to your architecture, where each pattern needs to earn its way into your architecture. Let the "forces" described with each pattern be . . . well, forceful. You need to let the patterns you're observing in your design and code steer you toward the appropriate combination of patterns.
You may think this approach would be difficult to follow. After all, architecture has this policy flavor to it-it feels as though it's supposed to somehow dictate direction before you ever write a line of code. And, at the highest level, this might be true. However, as you get into the teeth of your architecture, the actual patterns you choose to leverage can vary significantly based on the patterns of interaction you see within your specific application. It's these patterns, these front-to-back passes through the architecture, that should shape your selection of patterns.
It's important to remember that there is a cost associated with employing unnecessary or wrong patterns. Imagine discovering that in your architecture you've applied a series of patterns that are adding no value. The overhead of removing or replacing these patterns late in the development process can be quite painful.
To be fair, this problem was certainly foreseen by the founding fathers of the architecture patterns. They went out of their way to identify the "forces" that should be considered when deciding how-or if-a given pattern should be used. If you're an architect or designer, it is your job to give careful consideration to these forces within the context of your solution. Each pattern needs to undergo careful scrutiny, and its presence needs to be justified by something more than the thought "it seems like a good idea."
For most of you, this might seem obvious. However, even with the best intentions, you may still discover that your solutions are sometimes leveraging architecture patterns that aren't adding significant value. The real key is to avoid trying to spell out the use of every pattern before you know what you really need. Instead, if you're able to continually inspect and adapt your architecture, you'll be in a much better position to strike a balance between what is needed and what is simply another useless layer.