Wednesday 10 February 2010

Over-Engineering

Recently I have been thinking a lot about software design and software engineering. The importance of software design, as I have stressed before, is paramount in ensuring your code doesn't fall apart the moment you start trying to piece it together. The problem with programming however is there are nearly always 20 (or more) ways of solving a particular problem. Often some will be preferable to others, but nearly always you have to make some kind of compromise, and pick the lesser of two evils. There never really is a perfect solution, only the best one you can think of at the time, and there will no doubt be a helpful colleague to come and poke their nose in and tell you exactly how they would have done it instead.

Now when you come to design and implement a certain set of functionality, you are presented with a choice of possible ways with which to handle creating it. I have found there are two main approaches to this. The first is to think of a very rough idea of what you want, attempt to scribble some notes (doodles) in the form of some (very) basic design, and start coding. You are basically trying to achieve the functionality you want as quickly as possible, with little to no concern for who else will need to look at, or reuse your code. The other way, is to create an impeccable design, with a multitude of classes and interfaces that allow an array of functionality you might not even need yet, but you are planning for every eventuality, and for the system to be used over and over again.

Now I am pretty sure which one you think is better, and you'd probably be right. The latter sounds like what a proper software engineer would do, and this is probably true, but that approach might not always be the best or most appropriate solution. This approach is probably a good way to go if you are a professional, seasoned programmer, but for guys starting out, this approach can be completely overwhelming. There are so many levels of abstraction, and so many possible things to worry about, that it all ends up looking and sounding too much to take in and maintain.

What you want is the base functionality to work, and to be able to see it working. This is the best way to learn in my opinion and once you have these fundamentals in place you can start building a better design around them. There may be times when even professional developers take the quick fire approach, if it is a system that is small, and won't be used much, why make an over-engineered solution when you could code something up quickly, and then get on with more pressing tasks.

I am sure not everyone will agree with me, but it often feels like you need to walk before you can run, and there is no way you will create a flawless design without understanding the quick way of doing it first.

No comments: