The Path not taken…

EDIT:  I'm not suggesting that you ship code with known Technical Debt here and I'm sorry that I gave off that impression.  That was not my intent.



Say you're given a choice between two directions:

Path A:  Build a crude, simple, hard-coded solution to the immediate needs to get the first release out the door.  You know full well that some of this work will have to be modified or maybe even rewritten for future releases.

Path B:  Write an elegant solution upfront that addresses all of the needs, present and future, that you can forsee.

Every case is different, but my stock choice is Path A.  Path B might very well lead to a reduced effort in the long run, but it comes with substantially more risk.  But then again, you might be tackling a lot of complexity upfront in a speculative manner that can easily lead to wasted effort.  On the other hand, I really do believe that as long as you write maintainable code with the full gamut of TDD and CI practices in Path A, you can grow the code to handle future needs.

All that aside, the single biggest risk is what if the initial release fails?  You simply don't get a "future" if the first release bombs;) 


My younger sister told me a story before her high school graduation.  She was talking to the valedictorian of her class and was asking him how his speech was coming.  She made a typically sarcastic remark that she hoped he wasn't using an analogy to Robert Frost's "The Road not Taken" poem because it was a terrible cliche.  Sure enough, his face turned white and he ran off mumbling to himself. 

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
This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • jmiller

    You know ulab, part of my thinking is that I can grow Path A into Path B at a later time. A huge part of “good” code is going to be the ability of the code to be safely modified at a later date.

  • ulab

    I would go with Path A. The amount of personal stuff (code projects I wanted to do) I have not done is a lot because of Path B and the mental block I get because of B. B is good… but the brain freeze I get….

    I understand it is a evolutionary thought process….I went to B, then stayed at B(did almost nothing in coding in personal time), then moving to A (writing crappy apps in personal time, but they work ok and I get atleast sh** out).

  • Derik Whittaker


    Thanks for clarifying this, I like Bill read this as you asking if creating ‘technical debt’ for your initial release in order to see if the application is really what the user group wants.

    I agree 100% with you when you say ‘build a simple design in the initial design that only satisfies the first release’. If you are adding code into your application because it is going to be needed in V2, 3 or 4, then all you are doing is wasting your time as well as your stakeholders money.


  • Bill Pierce

    Hey Jeremy,
    Was reading your post in FeedDemon then came and read the comments. “crude, simple, hard-coded” sounds like “bad code with technical debt” on the first read. My initial reaction was no way would I take Path A. We might have different definitions of crude and hard coded. I completely agree that a good design should make refactoring a breeze from one release to the next. After a full evaluation your post sounds like a pitch for YAGNI, again, I completely agree.

    Also, there is no gaurentee that the second release won’t bomb so you might railroad yourself down Path A everytime. Why design v2 for the future because there may never be a v3?

    Just my 1.5 cents.


  • Jacob Eggleston

    In reply to Derik’s comment: IIRC, I think it was one of Joel’s articles that mentioned making the interface appearance reflect the finished state of the application. As sad as it is, you can show PowerPoint mockups to a client/user and if they look pretty, the user will often walk away with the impression that the work is 90% done. Then they can’t understand why you need to spend the next six months “tweaking the functionality of the app.”

    The user interface is the primary indicator people use to guage the progress of an application. I remember the article arguing the benefits (from a user satisfaction standpoint) of making a concerted effort to make prototype and early versions of a system look ugly and unfinished and polish pieces of the interface only after the functionality is done.

  • jmiller


    I think you misunderstood me a bit. Under no circumstances am I going to ship bad code with technical debt *by choice.* I just meant to build a simple design in the initial design that only satisfies the first release.

    Like for example, I’m not going to put in a bunch of Web Services that *might* be useful later when the first release is going to run completely on one box. As long as my code is well factored, I should be able to put in a web service after the fact when and if I do need it.


  • Derik Whittaker

    I would agree that getting something out the door is the most important thing. However you have to be carefull, if you present the users with something that ‘works’ (or at least appears to) you may be stuck in the situation where you are not allowed the time to go back and refactor it to be an elegant solution.

    If you know that your users / stakeholders will treat the initial release as a pilot or proof of concept, then I say Go For It. But my experiance has been that once they see something they like, they think it is done and it is very hard to tell the otherwise.

    My 2Cents


  • Derick Bailey

    I think you missed one of the choices:

    C) Build a moderately crude, somewhat simple solution with the extraneously complex items hard coded, and with enough elegance and planning for current needs to be flexible in the future.

    Of course, I’m not in a pure Agile/TDD/CI environment. My company hasn’t quite picked that up yet. I’m slowly progressing in that direction after having travelled the option B route for a few useless years. At this point my option C is working well for the company, and I’m hoping to migrate my team towards TDD and option A.