Sunday, December 02, 2007

How Developers Learn

I took a sarcastic look at developer motivation to learn in the last post, but let's take a look at how developers learn. First, let's detour briefly to the realm of behavioral science, where David A. Kolb created a chart categorizing learning styles.

I'm leery of the categorizations that social science tries to put on humans. You can't stick people in boxes because some parts of them won't fit and the ones that do might be trying to climb out. But I agree they are useful for identifying general traits and tendencies. You've seen these things before, possibly in your management or project management classes. Similar charts for categorizing personality types are used to help you empathize with teammates and understand better how to communicate with them.

David A. Kolb
Kolb wrote Learning Style Inventory in 1984. There's a nice summary of his theories of human learning at Don Clark's Performance, Learning, Leadership, & Knowledge site. Essentially, Kolb's theory is illustrated on a two dimensional grid.

One dimension represents a continuum that rates a person's tendency to be task oriented (doers versus watchers). The other represents a person's emotional state in learning (expressive versus detached). The extremes of each continuum yield four types of learning style:

  1. Concrete Experience: People that like this learning style learn best from the experience of others and information they receive hands-on. They favor anecdotal lessons, peer feedback, and direct experience with a situation over theoretical study.

  2. Reflective Observation: This learning style represents those that learn by watching others work and can ponder how it affects their life. Learners of this style appreciate having a mentor to learn from or an advancement structure where they can serve in apprenticeships and see how others perform a task.

  3. Abstract Generalization: This is learning via deep analyses of published theory and case studies. Learners preferring this style tend to reflect heavily on hypotheses and compare and contrast the theoretical against their own personal experience.

  4. Active Experimentation: Learning here is achieved through the "school of hard knocks." People using this method to learn like to jump right in right away. They probably don't have the patience to absorb large amounts of theory or to poll peers for advice. But hey, some situations call for Dick Marcinko and some call for Robert Gormly.

The intersection of the dimensions creates four quadrants that generalize the types of people based on their learning preferences.

  1. Theorists: These people are readers and thinkers. They prefer book study and tend to think in abstract theory rather than practical application. They might be what Joel Spolsky calls Architecture Astronauts.

  2. Pragmatists: Like the Theorists, Pragmatists will use abstract learning to study theories, but they are more interested in ultimately how they'll apply that theory to practice.

  3. Activists: Activists like to learn by just diving into something and learning as they go. They like to experiment and may be too impatient for the books the Theorists would use, instead relying on immediate feedback.

  4. Reflectors: Reflectors, like Theorists, need time to ponder and come to grips with a subject. But like Activists, they depend on concrete experience to help them make sense of things and determine how they'll apply them. Theorists use observations and studies to develop and challenge a theoretical model; the Reflectors use their observations and intuition to learn and apply themselves.

It sounds interesting and I do find Kolb's work fascinating, but then again maybe it's all a bunch of moldy elephant crap. As I said before, you can't categorize human beings with cookie cutters. Not all criminals are, as the liberals would have us believe, simply lonesome, misguided kids that can't help themselves and therefore shouldn't be locked up. Yeah, whatever. Maybe that's true for Dostoevsky's Raskolnikov, whose guilt drove him to turn himself in, but how many times does that happen in real life? I digress. The reality is that a person can use any of those learning styles and belong to several of those categories.

Learning Through Code
How can you help improve your company's applications and reduce time spent fighting fires if your developers don't have time to learn or advance their skills? If they're not motivated to do it themselves? After years fixing other people's code, and realizing that mine at times has been even worse, I think there are a couple of tactics that can help.

  • Document, Dummy!
    I know. I harp on this all the time. And I may be one of less than 20 developers in the world that actually care about it. But would you work on an engine without a Chilton guide? Would you build a house without a blueprint? Even a LEGO model without the instructions?

    Then why, with something as complicated as software, would you jump into 100,000+ lines of code without a map? I know the answer already: because the knuckleheads that cooked up that pile of spaghetti didn't leave a recipe behind! Forget it. I'm done talking about user documentation, technical documentation, and training. If you don't value it, that's your problem, and good luck with that as your application grows in complexity and your users start spreading across time zones.

  • Get a Decent Lead or Architect
    If you can't get a decent road map for a project, at least get a decent foreman. There's a reason young lieutenants are told to defer to the platoon's senior non-commissioned officers: experience and proven competence. This is especially important when the team is navigating the minefield of a new paradigm such as when adding substantially new chunks of functionality, porting the application to a different technology, or even retraining en masse to a new language. A good lead can help the team make good decisions and bypass common pitfalls. But leads aren't perfect; if the team is making the jump to something really different, get a consultant in that has proven expertise to work with the team. This is especially important because of the next point.

  • Make Version 1 as Clean as Possible
    You want to know how developers learn? Some will read books, some will listen to advice from the lead or architect. And some won't do either of the above. Maybe they're not interested in the time it takes outside of work to read books or take classes. Maybe they're self-conscious and feel that asking for help makes them look stupid.

    But every developer eventually has to dig into the code. Every one. Has to, at some time or another. It doesn't matter if they're supporting an old app or just looking for ways to write a new one, they'll likely try to cut-and-paste to save time. And this is where you can do good things for them if you've got good people leading the way. Regardless of their preferred learning methods, all developers learn from existing code. That means that if the bulk of the code is fugly, average developers are going to propagate those techniques forward.

    Good developers will try to improve things; they too cut-and-paste to make deadlines, but bad code smells will trigger a reflexive action and they'll at least try to clean it up a bit.

    Average or less experienced ones may not introduce worse techniques, but cut-and-paste still deteriorates the code because it expands the existing technique's use. That hardcoded routine that was already a maintenance hassle is now a maintenance hassle in two or more places.

    Poor developers will make it worse, by cobbling on even more hacks on top of the copied code.

    If you don't have strong developers maintaining an application, it's going to stay about the same or get worse. Everything from data access and variable naming standards to GUI techniques and script formatting will likely be carried forward from the original foundation. That means the application is well served by a decent version 1, assuming the software is going to live long enough to need continued maintenance.

Still, making Version 1 as clean as possible is no guarantee of a happy, extensible application. I've seen apps that had a decent first cut, but poor follow-on developers compromised it over time. And sometimes, the first cut is necessarily rushed and you could make a case that a good lead developer/architect is as valuable in the first several refactorings of the code as he/she is in the original design. Writers have an adage that applies here: The best kind of writing is re-writing. Perhaps the best kind of programming is refactoring.

Knowledge is Power
Software is hard. It almost always grows in complexity as it evolves, sometimes by design and sometimes by misstep. You can't do everything, but do everything you can to give your developers an edge against chaos. Lobby for thorough requirements, demand proper resources and tools, and get a good project manager to enforce scope control. And educate them, knowing that each person has a different blend of learning styles. Institutionalize the team's knowledge through documentation and impress on them the importance of keeping it updated, hold technical sessions, live training for both business and technical topics, give them a book budget, and for crying out loud, don't always say "No" when they ask to take external classes or attend technical conferences.