The Eleventh Principle: An idiom should only implement the functionality needed.

One of the coolest things about writing software is that we are creating something out of virtually nothing but our imagination and our ability to design something that works. And so it allows us to test our pet theories about architectural design, about the best way to solve problems with designs that are extensible and which can be generalized to solve even larger problems.

The temptation to do this exists on all projects. Even though we are warned constantly about premature optimization, we still do the equivalent when it comes to solving the immediate problems we have in front of us by extending them to more generalized solutions which we expect will help us in the future. But they almost never do: instead of providing us an easily extensible architecture which can solve future problems, we instead create something too complicated to maintain. And the new problems we face don’t fit into the solution we previously built.

Another example of solving problems we don’t have yet, only to make things confusing: suppose we have a table view which only shows a subset of the items in the table depending on a bit of business logic. This business logic essentially filters out the results of the table according to a function which takes an object from our database and determines if it should be visible or not.

In the process we decide that what we really need here is considerable flexibility in determining if rows are visible or not.

So we decide to use the Specification Pattern, which provides us nearly unlimited flexibility in assembling simple conditional statements into complex logic classes. We build our specification protocol:

Nearly a half-dozen classes, a hundred lines of glue code or so, but we are now prepared for that future request we know that is coming, of a server which may send over an arbitrary filter specification to our client which alters the behavior of what items we show on the table view.

This design model is conceptually relatively easy, too: if we have other predicates we may filter against, such as if the zip code is well formed or if the phone number is present, we simply create new classes for each test–then assemble them into a tree hierarchy for evaluation.

And when the back end sends us a promised XML file which contains the new filter specification, such as:

<or>
<filter name="HasName"/>
<filter name="HasAddress"/>
</or>

we can easily parse that using our specification classes and reload the filter used in our code.

A beautiful architectural generality to solve the present problem of filtering items if they have a name and address against a general purpose structure that can form any filter we can imagine from an arbitrary specification.

But will we ever use this generalized solution?

Well, in order to support this filter method, the back end needs to send an XML specification for the new filter. The XML needs to be authored–which implies a back-end page which administrators can go to in order to create new filters. The page needs to be created and maintained; the database entries need to be built and tested, the end-user administrators need to be trained, and the new filters need to be validated before they are deployed.

That’s a lot of back-end work.

Instead of sending this XML, it would be far easier to simply send a single keyword or index: “filterNameAddress” for our present filter, or “filterNameOrAddress” for an Or operation. Or even better, that could be represented by a magic number.

Dozens of lines of code in our application, and in the end, this is how we’d wind up using our classes: