Tuesday, August 11, 2009

Modularity in Software

Modularity – in the form of distinct manageable software artifacts as well as distinct logical concepts – is at the heart of any well-designed software system. Software that is not effectively modular may hardly be good and efficient.

Certainly, there is plenty of poorly written monolithic software that still does its job, but it is all but guaranteed to be error-prone, non-adaptive to even slight requirement changes, and present all sorts of maintenance problems. Most importantly, while it initially looks as if it is easier to write software without worrying too much about its quality, it is – without a doubt – much more difficult, time- and resource-consuming to bring such projects to any reasonable completion. Some people, perhaps, will argue that it is acceptable to put together a sloppy monolithic implementation for a throw-away application, or for an application whose life span is expected to be very short. However, for any serious critical real-world application, building a cumbersome mammoth of a system with no compartmentalized functionality, no clear functional domains, and poorly abstracted complexity is rather shortsighted and irresponsible. Not many people would actually argue with that. But how many real-life projects have elagant modular structures? Rethorical question...

To me, one of the most obvious signs of poor code is long monolithic functions that span multiple screen pages and hundreds of lines of code. Although there may be - theoretically, and very rarely - situations when a long (over 30 lines of code) method is justified, such situations are most certainly an exception to the rule. I generally avoid defining the maximum number of code lines per single method since it is partially a matter of taste and depends on the situation. Every attempt to set the limit in online articles and blogs usually provokes a storm of nasty comments - mostly from cocky spaghetti-coders who pride themselves in writing crafty unreadable code that they think is very brilliant. If you have read my previous post, you know what I think of such people, and I have no intention to argue with them. I would just say that functions should be short enough to be readable and easily understood, as well as represent only a single logical operation - with the complexity of sub-tasks abstracted in one-liners that are calls to the corresponding subroutines. There are always people who claim that it is unrealistic and impossible. I respectfully disagree. After all, all my code is written like that. You'd be hard pressed to find functions longer than 10-15 lines (including comments.) And let me point this out: I never do that intentionally, it just happens that way; I find it easier to write code that I can read and grasp at any given moment.

That's just my opinion. I could be wrong...