small medium large xlarge

25 May 2009, 19:06
Robin Newton (8 posts)

I was reading the Patricia Benner book, and came across a section (which, annoyingly, I now can’t find) where it argued that for training people at the higher skill levels it is more appropriate to present them with details of real cases than simple examples concocted just for training purposes - gives them more to get their teeth into, so to speak.

I’m reminded of a situation in a large company I worked for a few years ago. It had been decided that all developers needed training in object orientation. There was a great deal of experience and expertise in the office I was in, but nonetheless we all went along to a week of training sessions.

The trainer turned out to be a bit of an evangelist (sing hallelujah) and considered it his duty to give us the good news of Test Driven Development. He was given quite a hard time, especially by a couple of the more experienced developers. This, to be fair, he took mostly in good humour; but I think he thought he was dealing with stubborn old-timers who were dismissing what he was saying out-of-hand because they just didn’t get what he was saying. (I don’t think he cottoned on to the fact that they were giving him the third degree precisely because they were taking him seriously.)

In order to win people over, he did an extra session where we went through the Bowling Score exercise. (Using TDD to write a program that scores bowling games.) I think point of the exercise was in the final ‘reveal’, wherein we discovered that we don’t need various classes we thought we would, and that the whole thing can be done just using a simple array. At this point we would realise the error of our ways, see how old-fashioned design methods lead to over-engineering, and live happily ever after.

It fell a bit flat.

At the time I put this down to a couple of things. One was that most of us didn’t know how to score bowling games. I suspect that the trainer, being American, had taken it for granted that most people would know. Presumably the reason for picking bowling as the example (rather than, say, cribbage) is its familiarity. The other thing was that it wasn’t immediately clear that the final version of the program would never write past the end of the array it used: a possibility that C programmers would inevitably take more seriously than a Java programmer would.

However, there was something deeper than this. This was clearly a toy problem, but people treated as if it were a real, complicated problem because - in a training situation - it is appropriate to “play along” with the example in order to allow the trainer to make his pedagogic point. This being so, it is always going to be a disappointment rather than a revelation to find the point is “don’t over-complicate simple problems”.

All this managed to create the impression that TDD is only suitable for problems that are essentially trivial.

03 Jun 2009, 14:50
Micah Martin (1 post)

I, your humble trainer mentioned above, still believe that TDD is critical. I’m skeptical of any developer who calls himself a professional yet doesn’t practice TDD.

More to the point, Robin, if you recall, the bowling exercise took about an hour. The delema with real world problems is that they are complicated. To fully understand a real world problem it would take many hours and solving such a problem could take days. Clearly this is not suitable for a classroom setting.

Now, it would be possible to extract a nugget from a real world problem and use that for a classroom exercise. Of course it would take preparation before it was suitable. For example, you’d have to isolate it from the rest of the system so that the domain is grasp-able in a reasonable amount of time. You’d have to decouple it from otherwise vital constraints so that it’s possible to implement the solution within the span of the class. And don’t for get to practice solving the problem so that you’re sure it gets the point across. What have you got after all this? A toy problem.

Let me just add that I have used unprocessed, real world problems in the classroom before. In those sessions, I would undoubtedly receive feedback that the exercises were too complex.

17 Aug 2009, 23:26
Robin Newton (8 posts)

Yes, I can appreciate the dilemma.

I think the problem might be do with the tempo of development, as well as of the inevitable complexity of development.

Nursing has, I imagine, a rather episodic character: much of the work dealing with an on-going series of relatively self-contained incidents. Moreover, in many incidents it will be vital that the nurse can make their judgments quickly. This being so, it would be relatively straightforward to find examples from real life that be used in training - even being role-played in real-time - without taking an unreasonable amount of time.

In software development things are rather different, in that you have projects that might go on for months or years. Even simple task taken from a real project might take a day - which would make it difficult to use in training - and would probably require a level of contextual knowledge that might easily take a week or so to acquire.

The best analog I can come up with for a medical-style ‘incident’ is bug-fixing - specifically, investigating bugs encountered by users, rather than those found during development. I don’t know if they would be suitable for training, but I do think that a very good way of getting to grips with a complex system is to look into reported bugs.

Slightly tangentially, one of the things in Richard Sennett’s The Craftsman was the importance he attached to repetition in gaining skill: not the sort of drilling that you might use to develop a rather mechanical perfection, but as a means of exploring different possibilities and variations. (Mile Davis’ reply when George Russell asked him his musical aim: “to learn all the changes”.)

I think that in some occupations this kind of repetition comes with the job rather than having to be sought out. However, in software development it is much harder to find a rhythm that makes this sort of honing possible.

20 Jul 2013, 23:16
Robin Newton (8 posts)

On this topic, I recently came across a Venkat Rao post Strategy, Tactics, Operations and Doctrine, which was chiefly on the use and abuse of the word ‘strategy’ in a business context (in view of the military origin of the term). However, the quote that caught my eye was:

Tactics are abstract: they can be described in manuals with toy situations (for running a meeting or blowing up a bridge). Strategies are concrete: they are best learned through case studies of specific real histories about real people and places, with names (ever wonder why military officers and MBAs train on case studies rather than game theory?)

Put in these terms, Micah was focused on teaching Test Driven Development as a tactic, whereas I was interested in the possibility of deliberately learning programming strategy. In fact, it’s superficially tempting to say that operational, tactical and strategic levels in decision-making map onto beginner, competent and expert levels in the Dreyfus model. (Although for various reasons I don’t think that can be true.)

It might make sense to look to military and business styles of training for examples of what learning software strategy could be like, since software development is closer to these fields than to nursing with regards to time frames involved. So, one could imagine having people pore over evidence from revision control history, issue tracking, mailing list archives, etc, from over the lifetime of a project, in order to analyze what happened in a project and what their importance was.

I don’t think that typical end-of-project review meetings cut the mustard here, because

  • they are commonly conducted from a project management point of view, rather than a programming one
  • they treat people’s unprompted memories as giving sufficient detail on “what happened”
  • as a consequence, they tend to deal in generalities rather than specifics

Nonetheless, they might be the best we have at the moment.

20 Jul 2013, 23:17
Robin Newton (8 posts)

Recently I’ve been put in mind of the situation from my original anecdote - I’m still in contact with people from that company.

When I said that there was “great deal of experience and expertise in the office”, I ought to give a bit more detail. The company made a high end CAD system, and the team over the years had written their own rather sophisticated object system (with the unusual requirement of having to work with Fortran code). This system included orthogonal persistence (far superior to, say, Java serialisation) and something close to what these days would be called Software Transactional Memory. Moreover, they had their own automated build-and-test system, which I think is the nicest I’ve ever used.

What with work being divided up into 2 week chunks, a big emphasis on automated testing, close collaboration between developers and testers, project ‘post mortems’ etc., anyone observing development practice would have assumed that some sort of agile process was being used, despite a perception that this was just a slightly wonky version of waterfall.

On the question of test-driven development, one of the “old timers” I mentioned recently said this:

I am sympathetic to Micah’s problem picking an example; there’s no perfect solution. But I think Micah’s reply confuses their own version of “TDD” with “testing should be done and thorough”. Their version of “TDD” was actually “Development Without Design”, and that is what I was objecting to most. His flowchart for “how you write code” had a box after “run new test cases” labelled “refactor the code as necessary”, and I was confident that in an [high-end CAD product] example that would eventually turn into “we have to design our code now, because otherwise it’s going to be a tangled mess, and this is going to be hard work”. Micah refused to see the problem here. Doing a redesign every time a new test case fails turns an task that is (say) n-squared with the complexity of the code into a set of tasks that are n-cubed in effort in total. That would have been catastrophic for our productivity.

to which my response is

My take on this is that methodology is dependent on context.

Agile methodologies largely come out of the consultancy world. You have a single customer, fairly specific requirements, a limited time frame, and no real reason to care what happens once the project is completed. In this context it makes sense to say “Make sure you deal with the things that the customer really cares about. Don’t get bogged down in fiddly corner cases.”

The situation is very different for something like [high-end CAD product], which has lots of different customers, all of whom use the product in different and demanding ways; moreover, the code will be maintained over a long time. What might appear to be a corner case may turn out to be crucially important to some customer, and you won’t know until you accidentally break their way of working. That’s why it’s important to have a coherent idea of what counts as general correct behaviour. This is somewhat independent to ticking boxes for particular behaviours in particular testable situations.

My assessment may seem a bit doctrinaire. On the other hand, I recall Micah saying that a typical project for him took a few weeks from being given acceptance tests to shipping the end result to the customer; if there were problems, this was the customer’s fault for having written bad acceptance tests!

17 Sep 2012, 17:42
Andrew Hunt (222 posts)

So a few comments on the thread so far, going back to Micah’s early statement:

bq. I’m skeptical of any developer who calls himself a professional yet doesn’t practice TDD.

That sounds a little over the top to me. I think TDD has great advantages in many circumstances, but it’s not a cure-all. Nothing is.

In this last post, I think there’s some disconnect with the typical literature/trainer/consultant’s necessarily vague advice of “refactor the code as necessary” versus the realistic, if alarmist view that this is tantamount to “that would have been catastrophic for our productivity.”

Maybe I’m missing the point here (and that wouldn’t be the first time ;), but “refactor the code” to me is typically a mostly local activity, restricted to the one piece of code and/or functionality under development, and is aimed at making the code do what it does better more so than re-designing its purpose in life and tangling up the rest of the system in a redesign as well.

As with all things agile, if it hurts, you’re probably doing it wrong ;)


You must be logged in to comment