Evolution of a Developer (in regards to DI/IoC)

I’m putting together a new quickstart for StructureMap tonight.  In looking over my notes, I found a draft from earlier this year where I was trying to argue the value proposition of an IoC container.   I’m scrapping most of that post, but I wanted to share some thoughts on dependencies and structure in software designs.  My advice is to get yourself to bullet number 4 below in order to make your design, unit testing, and coding efforts more efficient – regardless of whether or not you use an IoC container.

I think the evolution of a developer’s mindset towards structuring applications goes something like this:

  1. Just gotta make this work.  There isn’t any separation of concerns.  Code responsibilities tend to fall wherever the developer happened to be in the code when he or she realized they needed something (what I refer to as stream of consciousness coding).  For myself in the late nineties, this trait manifested itself as popping open an ADO connection and grabbing an ADO recordset anytime, and anywhere, that I needed some data in the middle of a long ASP page.  I’ve worked in a couple different development environments and read code in twice that many since, but in my experience nothing leads to a big ball of mud faster than the combination of ASP Classic and developer carelessness.  The code worked, and that’s definitely something, but large amorphous code modules tend to be difficult to troubleshoot, maintain, and modify.  Plus, they can easily lead to duplication because code isn’t structured for reuse.
  2. The next stage is learning to put things in their place.  The developer has progressed enough to internalize the value of separating concerns into cohesive modules.  The developer is thoughtfully asking the question to himself or herself "where should this code go?"
  3. Wait, I’ve separated my concerns, but everytime I change one module changes ripple into other modules.  Each concern seems to know too much about the details and functions of other concerns.  Now we start to worry about being able to change how the system behaves by making isolated changes that impact the fewest number of modules as possible.  To make this happen we need to make sure the different modules are loosely coupled from each other.  At this point we begin to make much more use of interfaces and abstractions to reduce the coupling between modules.  We also strive to build modules that do not incorporate any knowledge of the other modules that the first module depends on.
  4. The developer is fully cognizant of dependency relationships in his or her codebase.  At this point we’re ready to consider using Dependency Injection and Inversion of Control to both further encourage loose coupling and exploit the seams in our application.
  5. The developer finally learns some completely new way of building software and feels like they’ve started all over again at phase #2.

I think the leap from #1 to #2 is huge chasm that many developers will fail to cross in their careers, but every following transition becomes easier. 

 

The following is a partial repeat of an older post, but I think it applies here:

Coder to Craftsman

When people first learn how to write code they necessarily focus on just making the code work, with little or no thought for style or structure, and certainly no thought for the future.  Any particular piece of code tends to land wherever the coder happened to be working when they realized that they needed that piece of code — or wherever the RAD wizards felt like dropping the code. 

I think there is an inflection point where a coder mindlessly spewing out code transforms into a thoughtful software craftsman capable of creating maintainable code.  That inflection point happens the day a coder first stops, lifts his/her nose out of the coding window, and says to him/herself "where should this code go?"  That might also lead to questions like "how can I do this with less code?" or "how can I write this to make it easier to understand?" or even "how can I solve one problem at a time?"  The rest of a developer’s career is spent pursuing better and better answers to the question "where should this code go?"

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.thesoftwaredevotional.com/ Michael S. Jones

    This is among my favorite blog posts of the year. You elegantly put into words what I think most experienced developers intuit regarding the progression of developers wrt loose coupling. I posted recently about loose coupling and included a reference to your post.

    http://www.thesoftwaredevotional.com/2009/02/loose-coupling-is-good-tight-coupling-is-the-devil.html

  • http://lalitkale.wordpress.com Lalit kale

    Hi jeremy!
    Excellent Post on how developer’s thought process evolves!
    Unfortunately,In Outsourcing world,as a developer I am forced to write a code which goes into #2 of this post.
    whether in my mind,I am already advanced to #3,the problem is I got isolated and appears isolated and get those dirty looks (he is so wicked,why he want to refactor when everything is working fine and concerns are isolated!!)

    Ah! Passion for writing better code is yielding me emotional storms!!

    Wish somebody who understand could hire me!!

  • Doni Grande

    >>> So how do you recommend training an eager kid out of college with little or no experience to get through these steps quickly?

    There is no quick fix other than to make mistakes, admit them, and learn from them. You can’t teach experience. Ultimately you understand good code by reading and writing good code. You usually learn to write good code by writing, and rewriting lots of code. And that takes time.

    If you look at the steps above, all but 1) involves active thought and effort on the part of the developer. It is hard work, but work worth doing.

  • Mike

    So how do you recommend training an eager kid out of college with little or no experience to get through these steps quickly?

  • http://jamesryangray.blogspot.com/ Ryan Gray

    It seems like TDD plays on the instincts of coders in phase 1 – ‘just get this test to pass’ is sort of like ‘just get this thing to work’. The problem is, you sort of have to see the bigger picture (IoC, DI, ORMing, etc.) from the outset in order to really see TDD shine. I think this is where the leadership of ‘architects’ comes into play; they have to say to the junior devs, ‘code it this way, kid… you’ll see how it all comes together later.’

  • http://blowmage.com/ Mike Moore

    @Jeremy Exactly right. You can find links to all of Neal Ford’s “Ruby Matters” blog posts off of the Alt.NET Podcast page on Ruby’s object model.

    http://altnetpodcast.com/episodes/10-oop-in-ruby

  • Jeremy Gray

    Great post all around, and will be promptly forwarded to my team as a reminder. That said, “Wait, I’ve separated my concerns, but everytime I change one module changes ripple into other modules.” makes me want to say “Then you haven’t separated your concerns, have you.” ;)

  • http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

    @All,

    I think Mike is referring to this from Neal Ford:

    http://memeagora.blogspot.com/2007/09/ruby-matters-place-to-put-your-stuff.html

  • http://blowmage.com/ Mike Moore

    If you are at the point where you are worried about where to put your code, then you should really look at Ruby. Ruby gives you a full OO object model and allows you to put your code in the exact right spot. And you don’t need a framework to manage the complexities you language introduces because it doesn’t allow you to put your code in the right place. Just sayin’…

  • http://home.infusionblogs.com/kszklenski/default.aspx Kyle Szklenski

    @Jim: That’s what I was trying to say, Jim. I think that rather than an evolution, most people go through a stage of reaching equilibrium – they go back and forth before finally settling on 2 or 3. Some of us go toward 4, and hopefully everyone reaches it! But we know that just doesn’t happen.

    As for professional apathy, I think that’s it. I’ve known enough people who were just “content” being the people hacking away. They have never really been interested in learning more, and they are very, very 9-5. Somehow, it made me want to quit my last job. That’s why I work for Infusion now, and happily at that!

  • http://bryan.reynoldslive.com Bryan Reynolds

    A good generalization of what happens.

  • http://webgambit.com Karthik Hariharan

    Great post. I agree with the major challenges involved in getting developers to cross the first chasm.

    Unfortunately there is a whole group of management types who think “getting it done” is the most important thing. Subsequently this leads to those who “got it done” being rewarded for what is perceived as “heroic efforts”. This thinking keeps many developers with a strong work ethic on the wrong side of the chasm for many years.

    I also feel that if you don’t cross the first chasm quickly, you won’t cross the second one at #3 to #4 at all.

  • Jim Cooper

    I’m often struck by remarks like this one:

    “make much more use of interfaces and abstractions to reduce the coupling between modules.”

    Use of interfaces and abstract classes can indeed lead to reduced coupling, but so many people seem to think that somehow their code is automatically better just because they’ve used an interface somewhere – and they quote comments like that to support their case :-)

    Similarly, I’ve seen IoC frameworks used to replace one line of code to create an object with 20 lines of code instead. Some people don’t seem to realise they are only really moving a factory from one place to another, and that there is no need if there isn’t a factory in the first place.

    I think these people go through some phase that you don’t have in your list :-)

  • http://flux88.com Ben Scheirman

    I certainly agree that most developers never make it to #2. Why is that? It’s not that we have to try that hard to convince people that the big ball of mud is not the best way to do thinks?

    Is it professional apathy? 9-5 mentality? I’d really like to brainstorm on ideas on how to shorten this “chasm.”

    Good post.

  • http://home.infusionblogs.com/kszklenski/default.aspx Kyle Szklenski

    Hey Jeremy,
    Great post, as usual. It brings back a lot of memories. I recall thinking, “Where does this code go?” in my C++ days, and deciding that it went into a global function in a header file, which modified/worked with the class that was also in that header file. As Scott Meyers says, that function should be considered part of the class interface, so I feel okay about doing it!

    On the other hand, at my last place, there didn’t seem to be a single coder who cared about where code went except myself. I think one possible variant that you missed, though, is the coder who evolves too quickly from 1 to 3 and goes overboard – trying to put everything into interfaces and/or abstract classes, and flaming out on the overall design of the system. Other than that, you’ve made me really want to try out StructureMap quite badly – I do not really use DI/IOC containers because they simply aren’t necessary for what I’m working on right now, but I am definitely going to start using them in my personal projects when the time for them is appropriate!

    You are an inspiring coder my friend.

  • http://www.rasmuskl.dk Rasmus Kromann-Larsen

    Excellent post Jeremy – you’ve really got those evolution steps down.

    I’m guessing this can also be tied into the steep learning curve of TDD, simply because this forces you out of #1. But it’s also been the one thing that has moved me the most.

  • http://www.agilification.com Jeff Doolittle

    I think a key stepping stone for me was when I began to branch out and learn how to use other dependency injection frameworks. This really helped with grasping the concepts of IoC and DI on their own terms, rather than in the context of a particular implementation. I’ve always come back to StructureMap, but I’m working on a Compact Framework project now, and it looks like understanding other DI frameworks is now going to be a necessity for me.

    http://www.agilification.com/post/Dependency-Injection-for-the-Compact-Framework.aspx

  • Ray

    Unfortunately it seems that in big companies where software development isn’t their primary offering, or where theres some organization that only does internal LOB development, most management only cares if a developer can get projects done. This ends up leaving most developers to hover around #1 and the few that are around #2 or #3 wanting to tear their eyes out with rusty ladles. In my experience, at least. Guess which one I am :-/

  • http://blogger.forgottenskies.com Steve

    Thank you Jeremy – I love these type posts of yours.

    As I reflect, I see those steps very clearly – the continual desire to create good code.

    I ask that question all the time nowdays – so something must be working :)

    Thanks again

  • Jim Kinter

    I think you’re spot on Jeremy, but finding craftsmen is a daunting task. I think that it’s incumbent on each of us to evaluate our work practices (individually and corporately) to continue looking for better and more efficient ways to achieve our ends. It’s this ongoing personal and professional commitment to process improvement that gives us, as software pros, a certain latitude and freedom that most other (IT) pros don’t have. I also believe that this is the core of the Agile movement that will ultimately [and finally] establish some credibility for our professsion, because although not perfect, when executed consistently and intentionally, in my experience, more regularly results in feature complete applications that are delivered on time and under budget…which creates a self-perpetuating loop. As a corporate ADM in a shallow talent pool, I REALLY want to see the adoption of DI/IoC, TDD, Agile, DDD, Palermo’s Onion architecture, etc. take off like wildfire because these things all help me to deliver better products, more consistently. The challenge that I have is that developers who “get it” are few and those who have had he chance to actually use it are even fewer…and then trying to be picky because I don’t want any egomaniacs, posers, or lone wolf personalities on the team leaves even less room to filter based on whether a candidate has made it to stage 4 or not…