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