My last post, I might be an elitist, but you’re a misanthrope, has kicked up a great conversation in the comments. There’s one viewpoint in the comments that I’d like to challenge a little bit. What if I’m working on small projects with very tight timelines? Many of the subjects that fall under the ALT.NET umbrella of interest like IoC, ORM, and AOP wouldn’t seem to be justified on a smaller project. Fine, maybe not, but the more basic design fundamentals that ALT.NET is also championing definitely apply to every project longer than a couple hours.
I’ve seen plenty of systems that were negatively impacted by code quality or a miscast application architecture. Roughly, I’d say that the two worst type of offenders fall into two general camps:
- Overengineered. Way too many abstractions that didn’t add value but did add complexity. Some of the problem is just creating the wrong abstractions and the wrong model, but much of that could be explained by using the tools from a large, complex development project on a smaller project where the tools weren’t justified.
- Underengineered. Brute force coding with little or no thought for abstraction or layering. By only using simplistic techniques or straight up procedural programming you may be writing way too much code and exerting too much energy. On a larger project finding the pertinent code can be a major challenge in its own right. Just throwing all the code into a bag full of very large coding modules isn’t going to scale. The danger to me in that “just Git’R Done” mentality is the fact that that attitude fails when you hit a bigger project. The biggest mess of a system I’ve ever encountered was a VB6 COM(+) system that began its life as a prototype and was rushed into becoming the shipping automation system for a Fortune 100 company. Typical circa 1998 VB6 methods of code construction didn’t scale to a system with 250,000 lines of code. Sometimes you need to reach for the more advanced techniques.
Admittedly, most of the biggest and craziest messes I’ve seen (including one of mine) fell into the first category, but the “under” category is just as much a source of wasted effort in software development today — even on smaller projects.
Most of us live under unreasonable timelines and expectations (do remember that Agile project management was partially created to give us a saner control over those very expectations). Yes, I think that the scale of smaller projects and problems doesn’t justify many of the same design patterns that I’d call mandatory on a larger project. I’ve reviewed several smaller solutions lately that were churned out in a hurry. In many cases I found places where the author of the code just plain wrote too much code. There were opportunities to pull out commonality into shared code (Don’t Repeat Yourself). Using the Composed Method pattern would have made the code much easier to follow when that code needed to be modified 6 months later. IoC/DI/AOP/DDD wouldn’t have been very useful in these projects, but a true working competency with OOP fundamentals would have cut the effort required to execute these projects.
My only point is that even small and quick projects can benefit from developers with a better skillset and knowledge. At a bare minimum, just knowing about existing libraries for common tasks would be helpful so you spend time solving the actual problem instead of rewriting log4net (true story) or wasting time writing ADO.NET code by hand (I honestly think I can use NHibernate easily enough that I would still use it on small projects). Even simpler projects need to be approached from a “Work smart, not hard” perspective.
To this quote from Andrew Tokely:
Should an application that has to be built
in a month, will only be used by a handful of people, that will be
rebuilt by something newer and better within a year or so, that doesn’t
have complex workflow or business logic, that really only needs to
persists data back to a datastore… really need to contain the level
of abstraction and testability of other projects?
No, the system he describes doesn’t need quite as much abstraction and layers and whatnot. Testability in some ways equals “the ability to quickly gain feedback on the correctness of the code,” so yes, you definitely want “Testability” in order to work efficiently at any time. In the case of a smaller system just pressing F5 might achieve the goal of quick feedback just fine — but if F5 isn’t enough feedback, you do need to care about “Testability” in design. Duplication of code, verbose code, and poor structure can still hamper even the smallest, simplest application in a way that detracts from your ability to execute in a timely manner.