Monday, May 23, 2011

Simple design as product architecture


What I'm about to express in this post is going to turn your world upside down, make you cry for help or worse.

A bit of history...

Since some late 1999 I've been creating what's called Enterprise applications. On some point they have been highly complex calculations of central heating and other pipe-related networks alongside with some flight planning system in Delphi and on the other end web sites (because that's what they really are) but with some huge backend in Java. And then some desktop applications in C#. All applications had one thing in common: they were unsustainable by a small group of people (say 3 smart guys) and needed a "team" of analysts, developers and (God forbid) configuration managers (I still don't know what the hell his role was!). They needed to work in "iterations", have defined "stories", maintain existing "system" and all that kind of s...tuff (damn, that was close).

Some thoughts to spice it up

During this more/less stupid time I've learned one thing and one thing alone: There's no such system that can't be decomposed, chopped with a master axe into pieces that are maintainable by hundreds of developers all around the damn world.
In one of my previous positions (which I hated so much I can't even begin to describe) I was forced to create database diagrams, then create domain classes (manually because this damn tool was not clever enough to generate Java code at all) and later on to keep them in sync (what was the guy that came up with this stupid idea thinking about?!?!?!), then to implement GUI in Java Server Faces (with no instant reloading of any fricken sort (JRebel did exist at that time if you wanna know) and - here's the damn best part of it - as a single, monolithic Java EE all go no quit application including in its beast's belly a CRM, Admin module, Shop, custom communication module, some master data editing.. pretty much everything in one big ball of mud. So here's how it went:

1. Code, code, code... code some more and then some.
2. Build, get a coffee in the mean time cuz it takes so damn long...
3. Ok - build is done - with errors - rebuild - next coffee (I'm becoming addicted to coffee at this point)
4. Build passed, deploy to Tomcat - and have a cigarette or two

Ok, so with JRebel this idiotic cycle is down to Ctrl+S and that's cool but our master of disaster (read: manager and architect in one person) didn't like the idea to spend extra bugs on software so we were stuck with this shitty workflow. Very frustrating indeed.

This was the first time I was writing an enterprise-grade application that I thought went completely haywire. In fact I was so convinced I couldn't work with this project no more and I decided to quit. As far as news go the team didn't have a release as of last week so after about 4 years of development the project didn't begun to earn money. CRAZY!!!

Sanity revealed

If creating enterprise-grade applications looks this way oh why would anybody do stuff like this at all??? The answer is simple and so painful: money! Some people even say that making such complex systems is fun. For the purpose of this blog entry I'm going to call them (quoting after Linus Torvalds) ugly and stupid. They should not be in the business - they should be in some mental institution taking their medication regularly.

Learning how to chop things to pieces is one of the most fundamental principles one learns when doing object-oriented programming. Somehow we forget that this same principle applies to the whole as well. It might be hard (hey, nobody said it's going to be easy!) to find the right balance between infancy and complication. But somewhere out there lies the right spot towards which all roads should lead.

Examples are what I like the most so I'm going to describe my idea by means of a project that most of us are familiar with - the blog :P

A blogging engine starts easy: a controller with a couple of methods (list, post), 2 or 3 views to display the data, one or two models to store this damn thing in a database - yeah! We've got a blog engine!
Then the real world kicks in and requirements start to pop up. We should probably be capable of administering the site, so we create a separate controller, do all the magic behind it and life is good again. And new requirements come in to be able to measure the popularity of the page so we create a filter to do the hard work for us. The adventure continues...

STOP! Isn't there something that we could extract and make it a separate module? As a OO developer you recognize the fact at once: there's a program that does more than one thing so the single responsibility principle is flushed down the toilet. Can't we do better?

As it turns out we can. Having a modular architecture for our application (be it OSGi or better yet Grails with plugins) can help us split the problem into pieces, implement them individually, have them tested to the bone and described so that when a newbie comes in he can take the docs and start coding right away. And before you say anything: since a module is doing one thing only the docs aren't that big. I mean, how much can you write about storing data in the database and then displaying them on a page, right? And if the blog engine turns into a full-blown CMS can't we have the management as a separate application? Will this hurt our feelings?

The same thing goes for calculations, statistics and god knows what else comes to that little screwed mind of ours.

Scalability === Maintainability

In the sense that things you can't chop you can't scale you can say the exact same thing about software products. If you can't split the problem into smaller problems you can't scale it to have many developers working efficiently on a product as a whole. But if you do you can hire hundreds of programmers, split them into really small teams and have them implement any system in a matter of (almost) weeks.

So you say you can't..

One thing I hear over and over again is "we can't split this up because.." and at this point I stop listening. The reason why is not important and is always the same: things depend on each other in a way they should never have.
We do have fantastic architectures like CQRS, CQS (being its predecessor), RESTful design and all that kind of belt of tools we can employ to make things chop-able (in a matter of speaking). The sky is the limit!

Reality is a bitch

Sure thing I'd love to live in a perfect world with requirements known up front that don't change till the end of time (meaning next version), perfectly feasible to code at all levels of abstraction developers and high quality standards met every day. The reality however means you have to get your hands dirty till elbows in some serious shit just to get the simplest things to work/fix (there you go - I've finally said it)

Live would be so ridiculously easy if we all wrote simple software.

1 comment:

Anton Arhipov said...

Great post! Reminds me of problems from my previous job :)

BTW, Would you like to have a 3-months JRebel license maybe?