As you know, the theme of this blog is kotan (枯淡), the Japanese word for the concept of the elegance one finds within simplicity. This is what I strive for every day in my code, my architecture, my designs, and in general, my life.
We often start out with the best of intentions and then, at some point down the road, we take a step back from what we’re doing and we think, “What the hell is going on here?” We started out trying to solve what looked like a relatively simple problem and things have escalated and exploded into a mountain of code, plumbing, infrastructure, and a potential maintenance nightmare.
Take a simple facade problem. Your company has a suite of services that provide functionality within your organization. You’ve actually done a great job at making these services isolated, durable, idempotent, and you’re proud of the work you’ve done. No data access is allowed that doesn’t route through these services. Now your company wants to expose some of this functionality to external customers.
This should be a fairly simple architectural problem to solve, right? You figure you can expose a thin facade layer of services on the outside of your organization which then just make calls against your internal services. Great, fire up the IDE and start coding. The first bump in the road – you can’t expose your internal service contracts to external customers because that forces them to be coupled with your internal versioning scheme. If you add fields that are only useful within your organization, you can’t drop that field as optional into your public schema.
So now you’ve got public schemas and internal (often referred to as canonical) schemas. Great. No big deal. Let’s just create some plumbing that maps the external messaging schema to the internal messaging schema. Now you need to come up with some of the things that most larger SOA implementations need like a service registry, you need logging, security, and so on. Worse yet, your infrastructure might be doing a bunch of context switching, changing between message-oriented and POxO (POCO for C#, POJO for Java, etc) oriented. Now you might have complicated code generation processes happening in order to make sure that your code objects always line up nicely with your schema-based messages … and so on. Recognize this pattern? 90% of our lines of code are not spent in support of business functionality, but rather are spent in ceremony. If you were to walk up to this system and look for the code that does actual work that advances company business processes, you’d probably see relatively few lines of code. The real problem is when you ask a developer to build a new service in the above scenario, they will spend the same ratio of time as we see in the code – 90% of their time coding ceremony and 10% of their time coding real, valuable, logic. This is neither simple nor elegant.
The point of this blog post isn’t to talk about SOA facades and message-passing architectures, that was just an example of how things can rapidly go from simple to incredibly complicated in a matter of hours. The point of this blog post is to shatter the idea that your code has an excuse to be bloated, complicated, difficult to read, and difficult to maintain simply because it’s enterprise code.
The next time you sit down and start hammering out code in advance of your newest, shiniest architecture, ask yourself whether you’re spending the majority of your time writing useful lines of code, or writing ceremony.
Here are some rules that I live by when implementing large-scale systems:
- If you think you’re wasting your time, you probably are.
- If you think it looks to complicated, it probably is.
- If you’re the only one who can work on it because maintenance requires too much context, you’re doing it wrong.
- If you think there might be an easier way to do it, there probably is.
- If you’re writing code for a feature you don’t know if anyone’s going to use, stop. (premature optimization)
There’s no shame in buying a commercial product or utilizing open source libraries so that you can focus on writing code in service of your company’s core competency and leave the ceremony to someone else.
To summarize – enterprise, back-end code has notoriously been big, bloated, complicated, hard to read, and nearly impossible to maintain. Stop the insanity! Enterprise code can be just as beautiful, elegant, easy to read, and easy to maintain as any other type of code – you just need to be vigilant and ruthless. If an architecture doesn’t let you write elegant, simple code (even if you’re the architect!), you need to cut your losses, put it out of its misery, and move on*.
* = We all have to make exceptions to accommodate budget, timelines, and alien-abducted-pod-bosses-from-Mars. Choose your battles wisely.