Sharing my thoughts on software development

Monday, January 9, 2012

The simple and yet complex case of KISS

I was blown away when first introduced to KISS principle. At the time, I was frustrated with how overly complicated our enterprise software was designed. It was a rewrite of a legacy system and our architect single-handedly wrote a custom framework on top of ASP.NET MVC framework, with the goal to make it more succinct and extensible.

The only problem, was that everybody was so confused about how it worked, that we lined up to the door of the architect with questions on how to implement particular logic. I carried that bitter taste of over-engineering for a long time, and have rigorously asked myself every time I make any design decisions, if my design was not simple enough...until now.

Today, a very smart and capable colleague criticized a simple piece of my code for being over-engineered, it was a surprise.The problem was fairly simple, so I skipped over things like IoC container, unit testing and the like, implementing only a very simple MVC design, with model layer logic located in separate project, using a single-class Micro ORM (PetaPoco) as opposed to a full-blown ORM.

In my mind, things cannot get simpler than this. Well, technically it can, like skipping the overhead of unit-testability, keeping all logic within single project, using built-in SqlDataReader instead of Micro ORM. However those measures only reduces complexity marginally, while making future refactoring exponentially more difficult. In my book, those are bad trade offs.

What I failed to recognize was that, you see, I have been writing code this way for many projects by now and all those concepts and code structures are intuitive to me. Writing and reading code structured this way is as straight-forward to me as code structured in the simplest possible way (TM).

This was not the case for my colleague.

He has different background than I do, and has grown different habits. All the "intuitive" project structure, the MicroORM, and unit testable code was extra complexity to him. While he recognizes the value of all those things, those are extra complexity that has no potential return due to simplicity of the project.

In the end, after some discussion with him and mental struggle with myself, I got rid of most of the "fluffy" stuff. I also lost the bitter taste for the "over-engineering" architect, after all, the gigantic custom framework that I found so overly-complicated was probably "simple enough" for him.

Lesson learned: Simplicity, like anything, is subjective -- what is simple to one person may not be the same for another. And when working in a team, you have to consider the whole team when making design decisions.