Don't architect software just for the sake of architecturing software.
Posted on Thursday, September 10, 2009 at 2:08 AM.Today I read an article written by Davy Brion a few months back. It talks about his experiences interviewing several developers, and some of the techniques and concepts that some of the candidates were and weren't familiar with. Namely, he found Java developers to be more familiar with dependency injection, inversion of control, test-driven development, aspect-oriented programming, object-relational mapping, and so forth. While he seems to see such knowledge as a benefit, I'm not so certain it truly is.
The Java community is well-known for their adoption of design patterns and frameworks. One of the most popular frameworks is the Spring Framework, which offers an IoC container, an AOP framework, a data access framework, and so on. AspectJ is widely used for AOP. Many projects use the Hibernate ORM library. And JUnit was integral in bringing test-driven development to the mainstream.
However, various notable software developers have suggested that design patterns are merely missing language features. In many cases, this does appear to be the case. Some common features and techniques of functional programming languages, for instance, render many design patterns irrelevant.
Unfortunately, design patterns and various frameworks have become quite embedded within some portions of the wider software development community. The devotion that some developers have to the "cause" can best be described as a religious in nature. It is particularly strong within the Java community, and to a lesser extent (usually Java expats) within the .NET community.
For every case when I've seen a techniques like IoC or DI used sensibly, there are many, many more cases of systems I've dealt with where they've became huge obstacles and only served to unnecessarily complicate the software system. The use of ORM systems is another frequent problem area. The first major problem that arises is usually performance-related, with the object mapper sometimes generating some truly horrific database queries, or bringing back huge quantities of data that are never used. In short, what was meant to save time ends up wasting it.
We often see these problems arise with business software. Often times, this sort of software is relatively simplistic in implementation, with most of the complexity coming in the various and often inconsistent business rules that need to be supported. So what I think we've seen in many cases is software "architects" who feel the need, for whatever reason, to build horribly complex systems where they're not needed. Design patterns, along with the copious use of frameworks and over-generalizations, facilitate this sort of development.
Soon, what should be simple systems quickly explode in complexity. The quality of the software drops, even though there may be a huge number of automated unit tests. Usability becomes a nightmare. Simple maintenance tasks and bug fixes take far longer than they should, because the developers need to unravel unnecessary abstractions.
Some of the most successful business software systems I've dealt with have evolved over time, often with different parts being written in isolation from one another. The only "frameworks" used were developed in-house, tailored specifically to the problems at hand. Any "design patterns" used were those that were observed naturally occurring in the software system as it grew. Instead of trying to provide overly-abstract and highly-generalized "solutions", each part of these software systems performed a very specific role, and did that role well.
So if we feel the need to start explicitly using design patterns or frameworks for our software, maybe we should take those feelings as a warning alarm. Finding a more powerful and expressive programming language may be a good place to start. After that, the reasons for employing design patterns or frameworks should be considered very carefully. It often ends up being quicker and easier just to sit down and write the software, rather than planning and debating and designing it. This is especially true if such techniques are used merely to add complexity to what should be a simple system, just to make it more challenging for the developers.








