Rightsizing your approach

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:

  1. 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.
  2. 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.

About Jeremy Miller

Jeremy is the Chief Software Architect at Dovetail Software, the coolest ISV in Austin. Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy is the author of the open source StructureMap tool for Dependency Injection with .Net, StoryTeller for supercharged acceptance testing in .Net, and one of the principal developers behind FubuMVC. Jeremy's thoughts on all things software can be found at The Shade Tree Developer at http://codebetter.com/jeremymiller.
This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://www.adronbhall.name/http://adronbhall.name/blogs/technology__software_development/default.aspx Adron

    It almost sounds like that last approach should or could just be generated to 95% completion. Seriously, generated solutions are used far too little to resolve needs just as you descibe for those “quick, I need something int he interim within one month for little money that does X, and Y and don’t care about Z”…

    With that said, what are your views on generated application frameworks. Any preferences? Ever used any in particular?

  • http://andrewtokeley.net tokes

    It is refreshing to hear a balanced approach to this – thanks.

    I was thinking more about my comments yesterday, trying to find better ways of articulating my thoughts. I see an increasing trend amongst developers I work with that they can’t possibly attain all the goals, visions and thoroughness of the ALT.NET movement. The end result is massive guilt. There are two consequences of this,

    - You do nothing – you are paralyzed by the thought that you SHOULD be able to achieve all this but for whatever reason you can’t.
    - You do everything – you try and achieve everything on every project and end up with more mess than you would otherwise – typically because of lack of experience in implementation or in deciding when an approach is appropriate. You often end up in scenario 1 above.

    The end result is a sad developer (and client). The message I want to spread is that (as you’ve said but other more fanatical voices haven’t) it’s OK to take an incremental and balanced approach to adopting better coding practises. Don’t feel guilty (or stupid) if you can’t achieve nirvana. Learn the techniques behind the concepts but more importantly learn when to apply them and the impact (positive and negative) of doing so.

  • http://bahadorn.blogspot.com Bahador

    In my opinion, if the project is small and on a short deadline, TDD is the first thing to be dropped.
    Even in that case, “Testability” as a design heuristic, can still be applied by an experienced developer.

  • Corey

    #2 States “Welcome changing requirements, even late in development. Agile processes harness change for the customer’s competitive advantage.”
    #12 States “Continuous attention to technical excellence and good design enhances agility.”

    For me it’s that mindset of, oh this will be replaced in a year, it’s delivered and then followed with… Oh this is great, and I know you’re going to replace this in a year, but can we do this…

  • Brad Mead

    This is a breath of fresh air.

    My attraction to advanced OO/DDD principles centers on making those (mostly) small/medium projects I work on more robust and less Git-R-Done. Sometimes I start down the SRP path but later abandon when time constraints press hard. Actually that’s a cheap rationalization. Without working in a progressive well-staffed Agile shop that actively mentors junior and mid level developers many of us are left to our own devices as to where to improve and what to implement “smartly” at any given time. Those of us without mastery but with passion and stuck in these learning-abyss type jobs have one terrible mandate – “spend your free time delving into advanced techniques”. I have often shrunk away from that mandate but never forget that it IS my responsibility if I value my career path and look upon the products of my labor as a source of pride (Thus Evans DDD remains at the top of the reading digestion list until completed).

    Steadily I hope to hone those code recipes that fit a given project and at some point become nimble enough to produce a modicum of success in any environment… To this end I have been really enjoying the “first causes” posts. Thanks for challenging my lassitude with this one.

    And yes I know… find a good agile shop at which to work :-)

  • http://kohari.org/ Nate Kohari

    Excellent points Jeremy. However, I’m of the opinion that IoC is a mindset — much like TDD — and can be effectively applied to all projects, large or small. As it is with any framework-supported methodology, your framework needs to work for you rather than against you.

  • http://arcware.net Dave Donaldson

    No matter the size of the project, I always put NHibernate in place. Seriously. It’s a no-brainer for me at this point because it solves the data access problem and allows me to focus on the areas that provide better value.