One of my favorite TV shows is Archer, which is about a fictional spy agency and its hilariously (and generally incompetent) employees. In the current season, the agency is basically attached to the CIA and its handler, Slater, who concocts very plans that he expects Archer and crew to pull off, but most of them go awry because a) that’s kind of the point of the show; and b) the plans are very overwrought and complicated.
In the most recent episode I watched, the prince and queen from Durhan (a fictitious Middle Eastern country) will be in town looking to purchase real estate as part of a move to New Yrok and Slater’s goal is to obtain the prince’s handprints and eye scans. To facilitate this plan, he wants Cheryl (an incredibly dumb but insanely super-rich secretary) to pretend to be a real estate agent and show them her mega-mansion as a potential property. The plan then calls for her to walk through them the greenhouse where Ray (one of the agnents) will douse their armed security guards with a powerful transdermal diarrhetic. Once they run off, Archer, Lana, and Pam (posing as a butler and maids) will escort the prince to the upper level where Slater will tranquilize the prince, get the handprints and eye scans (within a 60 second window), and make his getaway before the prince wakes up.
For various reasons, the plan does not go off without a hitch and for most of the episode, various characters comment on how complicated and involved the plan is and how it will never work. At one point they begin comparing Slater to Wile E. Coyote and his crazy plans to capture the Road Runner. If you’ve ever watched the classic Wile E. Coyote cartoons, most of his plans require precisely positioning the Road Runner on a specific spot for a trap to be sprung, and typically that occurs by offering free birdseed. And finally towards the end of the episode (right before it completely falls apart and they have to flee), they utter a line that really resonates with me as far as software development (and also project management goes): all this plan needs is a sign that says “Free birdseed.”
All this plan needs is a sign that says "Free birdseed."
This really struck me for a variety of reasons. How often, when we get involved in a discussion of architecture, do things get severely overcomplicated? How often do we lose sight of the actual problem at hand and try to solve a more interesting (but largely tangential) problem? How often do we try to plan for and build in all sorts of extensibility only to be proven wrong? In my experience, especially in larger, more traditional corporate environments, quite often. It’s quite often that architectures are designed by a committee in PowerPoint and not by people that have to build the system. Or are devoid of practical considerations at all. Or the entire effort is a wild guess at what the user might want in the first place.
A central tenet of Agile design is: do the simplest thing that could possibly work. Now of course there’s considerations beyond just functional correctness, but I see too much of a tendency to overcomplicate things that should be simple or to add too much functionality that isn’t borne out by any requirement. I confess I suffer from this myself too, probably quite often. We’re batting this around at work right now with regards to caching. As we’ve begun deploying more WCF services, we’ve noticed that some of them make use of fairly static data so there’s interest in adding some caching. These are things like states and provinces or some past enrollment data for candidates, they can change, but the rate of change is measured in months (or sometimes years). I pitched just using ASP.NET’s in-process caching (ObjectCache) applied as a decorator around service calls to the source system. The benefits to this were it was fast to implement, and didn’t require any new infrastructure (and the time and cost to evaluate and possibly license something). The negatives: since we have multiple load balanced services, each would have its own copy of the data. So one of the consultants moved away with this implementation and so far so good, it had the intended performance gains as we’re saving queries to the remote system housing all the static data.
We subsequently got a requirement to allow pre-loading or reloading of the cache. In other words, once the service is running and the cache is loaded, it will never expire its local copy unless the service is restarted (or AppDomain is unloaded, etc). We batted around using a timer to expire it (even though ASP.NET timers are not generally a fantastic idea), but ultimately our chief architect told us he wanted to separate this type of cache loading from the application so that an external body could load it and the application could just make use of it. It’s at this point I applaud what we did. The consultant wanted to build a super-involved cache management dashboard and a central application to allow loading the caches of any service (via some method the service would have to expose), but my argument was: there’s only 2 or 3 of these at present and the ROI for building such an application is low. And ultimately if we wanted a richer, more powerful experience we should seek out a distributed cache at that point. So instead, we went low-fi: a console application + a Windows scheduled task that simply calls a particular service method on the service to load/reload the cache. Some may find this horrifying, but I’m quite fond of it because it’s not overly complicated, it works great with minimal investment, and the pattern can be continued until such time as we want to do something more elaborate. All along the way, we’ve had to fight the urge (by lots of parties) to overcomplicate the problem and find the simplest thing that could possibly work, but in a proper operational nature and at least here, I thought we did a good job of that.