Pre-Code Design: When To Start & When To Stop

Alright, pre-coding design. By that, I mean, the serious thinking one does before one starts typing code into the computer.

The first puzzle of pre-coding design is to identify when to start & went to stop.

Start When You Have A Story

When to start: when a story has been selected for implementation.

That starting condition will be tricky for noobs, so let me blather for a minute. There’s no time to discuss stories in general, but in short, by story I mean “slice of functionality that goes from ‘pixels to registers and back’ doable in less than a couple of days.”

All the way in and out is very important. A couple of days is very important. There’s other very important, too, such as valuable, and some unimportant parts noobs often think are most important. No way we have room to discuss how you get to stories like that, we’re gonna stash that for another day.

Now, don’t go off telling everybody I said they should shut up until we have a story picked. We’re gonna talk, kids. We’re gonna talk, and it’s gonna include design ideas. We need that burble of ideas and insights before we even pick a story, after all. That’s fine. What I’m saying is, don’t take it very seriously. Sketch this, poke at that, look this up, schmooze it all over. That’s fine.

But design that specifies changes at the code level in any detail at all waits until the story has been chosen. You start when you have a story and you’ve decided to implement it.

Stop When You’re Excited BUT Nervous

When to stop: when you are at the place where you feel excited that you’re probably right but nervous that you might be wrong.

This surprises a lot of folks.

People who’ve dabbled in this movement will have encountered a great deal of railing against “Big Design Up Front”, and they think that means there’s no designing allowed. They’re surprised I encourage us to design at all. Relax. The method works for you, you don’t work for the method.

People who’ve trained and worked their entire careers old school, on the other hand, think that this is way too little design. One hears the word “cowboy” among the epithets. Relax. We’re not done designing, we’re done pre-code designing.

“Hey. I think we got it.”

That’s the sweet spot for stopping the pre-coding design. Notice that “think” isn’t “know”.

If You Pass The Big Black Bulldog With The Droopy Eye…

Let me throw out a few “too far” indicators, so you can get a feel for that sweet spot to start with. If you pass any of these points, you’ve gone too far in your pre-code design:

* you think all the thinking is done.
* there’s zero risk.
* you’re so detailed there’s a program that could just translate it directly into code.
* you can just send all the lesser lights out to type it in.

Right? If you see one of those droopy-eyed bulldogs you’ve taken that pre-code design too far.

Keep Going Past Where The Dairy Queen Used To Be…

Well, if we’ve got “too far” indicators, let’s look at some “not far enough” ones.

* you have no idea what files/modules/objects are likely to change.
* you are terrified it won’t fit in a couple of days.
* you don’t know how you’ll respond to a generic failure in the new functionality.
* you don’t know how you’ll enable/disable the new functionality.

When you hit the keyboard, you want just enough to make you feel you know where to start typing. Don’t worry that you haven’t done enough thinking. You haven’t, and that’s the correct situation to be in.

Hey, That’s A *Feeling* Not An Algorithm!

Yes. It’s a feeling, not an algorithm. (The force is strong in this one. <cue eye-roll>.)

There’s no computable algorithm for determining when you’ve done enough design. Very intelligent bozo’s have been trying and failing to find one for quite some time. Or, maybe there is one, maybe one exists, but it doesn’t matter because we don’t know it yet.

And before you bemoan this too much, try to remember: the current non-computability of the software design problem is why you aren’t on the night shift at 7-11. Or hiding from SkyNet in the rubble.

So you’re going to have to go with your gut.

Collaboration May Be Called For

The decision point will vary from one context to another, depending on factors including but not limited to: codebase knowledge, mad geek chops, domain knowledge, really offensive arrogance, number of eyeballs, most recent collossal failure, etc.

In a collaborative situation, people will disagree about their gut feelings. I’ll offer a pro-tip: don’t disrespect folks who are less confident than you. Find a 50/50 compromise, then bias it a little towards the nervous side, and do it explicitly and openly and cheerfully. The time difference isn’t that significant. Good nervous cheer from your pair is very significant.

(On the other hand, I usually resist compromising with corporate handbook nervousness. I especially target here company-wide design rules, which are nearly always borked beyond any ready solution.)

Is That All The Design We Do?

Of course not.

The stopping point above isn’t the stopping point of design, far from it. Remember, we’re talking here about pre-coding design.

When we say we’re ready to code we most definitely don’t mean we’re ready to not design. The real design is just heating up, in fact. All through the implementation process we will be making further design decisions.

The fear is that we haven’t done enough thinking to really solve the problem.

The reason we have that fear is because that’s the situation: we haven’t done enough thinking to really solve the problem.

But I’ll let you in on a little secret. Thinking is done with thoughts. Really solving the problem is done with code. You will never really solve the problem by thinking, you will only ever really solve the problem with the code.

That doesn’t mean we don’t think. It means we think enough to code, then enter a tight little cycle of code-think-code-think-code-think.

Design Enough To Code,

Then Code-Design-Code-Design-Code-Design

Defining Agile: A Musing

Sooooo, I saw a couple folks arguing earlier about what is or isn’t Agile.

That’s okay. People do that. Analytical people *thrive* on doing that. Anyone who’s gotten to the level of journeyfolk in any arena will seek to define that arena. All very healthy stuff.

Nowadays I tend to avoid these arguments. I have my reasons.

First, there is no definition anywhere on earth of anything that can’t be abused or misused willfully or not. There is no compelling conceptual locus that can be framed in mere words such that we can use those words to decide what’s inside the area and what’s outside of it.[1]

Second, I get bored easily. Remember, these wrangles are nearly 20 years old now. Spend some time at Ward’s Wiki. We discussed extreme everything. Extreme banking, extreme housebuilding, extreme *everything*.

Third, I don’t myself use “Agile”, except in uncomfortable situations.

Two Poles and a Broad Spectrum

There are two poles in most such discussions, with a spectrum between them.

One pole says “agile” means subscribing to the spirit and the letter of the document known as the Agile Manifesto.

One pole says “agile” means whatever the speaker thinks is best.

That second pole includes many folks who believe they have a grip on the spirit but aren’t necessarily even interested in the letter. It has many other folks — I’d say many more — who have solid connections to neither the spirit *nor* the letter.

Some Actual Cases, Bizarre to Me

There are folks who think there’s an agile way to hire lots of crummy geeks, pay them shit, and use control technique to make it work. They want to call this agile.

There are folks who think agile doesn’t require working software frequently released, or testing, or any given one or several of the original pillars.

Yesterday I heard of a team that does agile planning much more quickly by cutting out all the discussion.

There are many people who think agile means hour-long standups and month-long iterations.

I know folks who believe scrummastering is just another word for coaching, and others who think coaching means spreadsheet maintenance for management. Chat about it on twitter for a bit, and you’ll see tweets from people who sell “agile” tracking systems that count hours for management.

Companies like Microsoft claim agile. *HP*, saints preserve us. and many other hulking command and control giants. Hard for me to take.

Not so long ago I spent 5 months obtaining a thirteenth computer for a 12-person team that is the only team in their department that’s shipping successfully, at a Fortune 500 company with a whole agile software delivery department.[2]

I am not imagining this. Unlike a lot of folks, I work with these people for a living. Not just one company or team, but *many*. This list isn’t based in my reading, but in things I’ve observed directly or from one step away. It’s the vantage of being a well-known external coach.

Me and Agility

What I call agility is a mental stance, a kind of philosophy of geekery.

And tho I bitch at the Agile Manifesto a lot, it does in fact do a reasonable job of describing that philosophy.

There are a couple of things to remember about “agile” as a term. It emerged at a time when the folks using it were noting and seeking a unity between some disparate methods. They were also seeking mindshare. In those days we were all hungry for mindshare, because mindshare meant sales and sales meant we could keep doing this cool thing we were doing.

We wanted mindshare. We got it. To get it, we softened our case. We made hard things seem easy. we spread the word.  Along the way we muddied things by changing — rightly — our behavior and our prescriptions and proscriptions.

And yes, we invited in and even encouraged hucksters and lightweights.

We marketed.

And if we — I — now regret that, well, hell, I’m reasonably confident it won’t be the last thing i do that I regret.

[…] so that they know just exactly how a thing of beauty is a joy forever and forever and how it never never can quite fade into money-losing nothingness.

That’s Ferlinghetti, speaking of art directors and their relationship to art. (Read the whole poem, as it’s my favorite by him and one of my top half-dozen or so all-time poems. It’s meant to be declaimed, so declaim it.)

What I Do

I help teams find paths to becoming more like the people they wish they were. I call that “coaching”.

I don’t attend much to best. Instead I spend my time focusing on next.

I live with teams, learning what they do and how they do it. And I open them up to possible changes, in technique, in organization, in social behavior, in goals, in ways to think about problems.

I don’t — can’t — make anyone change. I never give orders. I only propose, describe, demonstrate ideas. Over time, teams ask me for ideas, cuz the ones I’ve offered that have been tried have helped.

And I wanna stress, they’ve helped in practice. That is, real problems the team experiences have been mitigated. Problems don’t happen to teams in theory, they happen to them in practice. That means the solutions have to, too.

This is what I know: I know that if you show me a hurting software development team, I can often, by no means always, help them not hurt.

I also know I do that by things that go largely unmentioned in any manifesto, agile or otherwise. I act-then-listen. I experiment. I attend. I am kind and, roughly speaking, cheerful. I got mad geek chops. I am fundamentally a silly person full of odd habits and odder passions.

Am I An Agile Coach?

Is that agility? Am I an agile coach? Are all the changes I propose “agile”?

I don’t care if that’s agility.

I don’t call myself an agile coach if I can avoid it.

The ideas I propose are based on my experience and my philosophy. Both have been influenced by the agile movement. But they’re not mostly “agile”, they’re just good local stepwise answers to bad local stepwise problems.

What does “agile” mean to me? It means “a set of insights that gradually morphed into a nearly empty abstraction”.

Not Hating the Arguers

I get it. I get it why it makes people angry to have the word mean just any damned thing at all.

I get it why some folks want to extend the notion of agility to cover agile-spirited ideas.

I get it why one would argue when I hear some would-be agilist advocating behaviors that don’t seem even conceivably to match the spirit.

I get it even more more more when I see that feeling coming from a manifesto author. Yes, it was a marketing and business decision, but it was also a heartfelt effort to collaborate in sketching a way forward in a very broken world.

Arguing About Agility Doesn’t Help Much

I Focus On Helping Much

[1] That’s not just an intellectual stance for me, but a daily one: I really don’t have the experience that truth fits in language, so I don’t spend a lot of time trying to make it do so.

[2] I’m not talking about a super-computer here. I’m talking about a computer that would have cost less than one day of my billing to get. And yes, Virginia, I did offer to take the day off and show up the next day with a new box. I always do. They always decline.

Turn Preasons Into Reasons

A remarkable amount of geekery-advice comes in the form of rules & slogans accompanied by appealing. intuitively correct, theoretical reasoning using simple logic applied to pre-existing abstractions.

I’m gonna pull a GeePaw-ism here and relabel “appealing, intuitively correct, theoretical reasoning using simple logic applied to pre-existing abstractions”. I’m gonna shorthand these to “Preasons”.

So. We get a lot of preasons in our trade. And they’re applied at every level, including but not limited to Coding, Designing, Tool-Using, Planning, Teaming, and Managing.

Why do we use preasons at all?

Well, simply put, we’ve no choice.

If I don’t know how to do a thing I have to make a guess about how to do it. If I am remotely interested in success, I have to have get some preasons, choose among them, and give my favorite a try. There are lots of ways to gather preasons, including making them up myself. (There are even preasons about the best way to do this.)

The only possible fix for that is to always only do things one knows how to do already.

But doing only things you already know how to do is a losing proposition. It will lose in business. It will lose in geekery. It will lose in management, and so on and so forth.

We have to change to win, and that means we have to have preasons to guess which change will work.

Why do the geek trades use so many?

I’m told by people in other trades that it applies to all trades equally. I don’t believe it.

It’s true I have only a passing familiarity with most other trades, so I could be wrong. But in my experience, preasons dominate the geek trade like no other. I see this every day in my work with teams all around the world. I see it in my RSS feed and I see it in twitter.  I see it extensively in hucksters and third-rate thinkers.

I have come to believe there are a variety of factors that cause this huge reliance on preasoning in geekery in particular. But if I lump all of these factors under a single rubric, it would be this one:

Ignorance-Discomfort: we don’t know how geekery works yet and we really don’t like that.

So what’s wrong with preasons, anyway?

Nothing is wrong with preasons. Something is wrong with how we use them.

Regardless of whether any given preason has merit, there is one thing that every preason lacks, by definition. Preasons are always “pre-“. Pre-experience. Pre-results. Pre-data. Pre-implementation. Pre-local.

Preasons don’t account — can never account even in theory — for the actual experience of the actual team that is actually acting on them.

Now, this isn’t the fault of the preason. We absolutely have to have preasons when we don’t know what to do. There is simply no way around them. We cannot know with certainty the result of applying a given preason to our given situation until we apply it.

The sin isn’t in using a preason. It’s in not reviewing the result from using it.

Preasons don’t become reasons automatically.

I got this theme, you’ve already heard it: Act-Then-Listen is the fundamental template of successful geekery.

What I am aiming at with that theme is a failure pattern I see again and again. We grab for a preason, use it to justify an action, then grab another and do the same, ad infinitum, ad nauseum, ad legacy, ad enterprise, ad ass-hattery on an intergalactic scale.

In the act-then-listen pattern, the listening has equal value with the action. In the preason-act-preason-act-preason-act pattern, the listening is what’s missing.

This missing step, the part where we listen to see what effects our action has, is how we can convert preasons in reasons. If we don’t listen to our own results, preasons never become legitimate reasons.

If we fail to do that conversion, in a world in which there’s so much we don’t already know, we’ll create something as awful, useless, demoralizing, and largely ineffective as — well — the geek trades.

So How Can We Change This?

There are lots of things of specific things we can do differently, depending on the various domains and preason-based actions. But generally? These things:

Suspect all systems for developing software. All of them. Suspect anyone claiming to have a drop-in system for you or your team. Anyone. We do not know how to geek, still less can we tell people how to geek using abstractions applied from a great distance.

Suspect “try harder” answers to negative experiences. I am not saying here that you don’t have to try, or that you don’t have to practice. I’m saying at some point, a long sequence of “try harder” has to be replaced with “try different”. How long? It depends on context, but my generalized advice to the mode of the bell curve: shorter than that.

Suspect large resource commitments to preasons. Large resources include millions of dollars, your entire software development enterprise, any step that takes longer than a breadbox. Even if your current preason-experience with a project or a sub-team is positive, roll it out one step at a time.

When You Don’t Know What To Do,

What To Do Is Act-Then-Listen




Estimating: Stop Trying Harder

(Note: Lightly edited and adapted from a twitter thread, where I’m @GeePawHill. Noobs be advised, I speak freely there.)

Accuracy in estimating software development times is a powerful example of forty years of “try harder” not producing any positive results.

Now, given some small change X and some substantial knowledge of the current state of my software, I can usefully estimate short-term work, from a few minutes up to a 50% hit-rate around about a week. This is because I have been a successful independent programmer for 35 years.

Without making any ridiculous boasts about my mad geek chops, I can still say this: I am good at programming, and very experienced. I am telling you that my estimating skill starts having more misses than hits in units measured in single-digit days. And that is when I have strong knowledge of the existing code base.

A week. Maybe two.

I Have Seen This

VLCAs[1] routinely spend weeks estimating things that are months away. And they do it over and over again in spite of the lack of consistent value.

Companies spend millions of dollars on this waste, then won’t buy hardware for their teams, even teams that are currently winning. (I am not exaggerating for effect. I know I often do, but I am not doing so now. Sometimes I say such strange but true things that I have to make this clear.)

The dollar waste is truly staggering. And dollars don’t begin to capture the cost in team stress.

It is to laugh. Or cry. I can never quite decide.

This Theory Is Bunkum

They patiently explain to me, as if I were a goodhearted but somewhat simple neophyte, the theory of how their planning works. It’s centered around the sophisticated concept of something called “addition of numbers”.

Sadly, the numbers are a) made from whole cloth, b) made entirely without consideration of each other, and c) not able to take into account even minor changes in market.

Why are people so resistant to the dramatic evidence that comes from every side of our trade? I think it’s a combination of confirmation bias and third-rate thinking.

People have any two successes in a row and they think they’ve discovered a method. Sometimes it’s just one partial success. When they have three in a row, they give it a catchy acronym and pretend it’s a system others should pay to learn.

A Cheap Experiment And A Proposal

Flip a coin and see how long it takes you to get 3 heads in a row.

That’s what a 50% success rate looks like.

When it happens, do you believe you have invented a new technique for coin-flipping, require it of all future coin-flippers, and start buying up clever domain names to advertise it? If so, I have any number of wagers I’d like to make with you. I will travel, if the stakes are sufficient.

For a small handling fee, I’ll even procure your domain names for you.

What Do We Do Next?

Meanwhile, in that same part of the forest, VLCAs constantly ignore the far more urgent question: what is the next most important change we should make?

Not only is “what’s next” more important than “where’s it end when”, it’s also vastly easier to determine. No one can describe the state of their software a year from now. Everyone has an idea about the next important small bit.

Now, given that we have failed at this accurate-long-term-planning thing ten thousand times, maybe we need to rearrange things so we don’t have to do it at all any more.

You can know where you are now and where you will be tomorrow. I mean, literally, “tomorrow”, not metaphorically.

Try Different

It seems strange to have to coach giving up, but that’s what I do. Please give up trying to predict the state of your software a quarter from now, because it can not be done for less money and time than spending a quarter getting there.

They say, “If we don’t know the future we don’t know the optimal way to get there.”

I say, “You can’t know the future and you can’t know the optimal way to get there until it is past.”

Change your business model so you don’t have to reliably predict the state of your software more than a month ahead. There are myriad ways to make this happen.

Or continue to spend hundreds of millions of dollars every year to not get what you want, in service to some over-simple theory, in the absence of consistent real data that the theory is valid.

Optimize Knowing What To Do Now

[1] VLCA is a GeePaw-ism: It means Very Large Corporation of America, an allusion to the Monty Python short called “The Crimson Permanent Assurance”, typically but not universally shown as the opening short film before “The Meaning Of Life”.

Me & Molly & Marvelling

I’ve been having a lot of trouble getting to sleep lately.

I go to bed cuz it feels like it’s time. Sometimes my body won’t settle, itching and twitching and such like. Sometimes my mind won’t. Usually it’s a mixture of both. So I get back up. But then I’m tired as hell, and it seems like I’m sleepy again, so I go back. Rinse, lather, repeat 3-5 times.

Eventually one of two things happen. Either I finally manage to pass out, or I get up and move out to the deck and sleep on the couch. Sleeping on the couch by myself seems to help.


This is Molly, freshly be-coned from having been spayed yesterday. She, her little brother Wobbles, and my wife all share the bed with me. Since Wobbles is still just a little one, 11 weeks old, we close the bedroom door at night, to prevent accidents and chewing out in the rest of the house.

Sometimes when I get up Molly will come with me, other times not. If I move quickly she just stays in bed and then the door closes and she doesn’t pursue. It’s openable by her, but not readily. It’s kind of a “press-fit” and takes some effort.

The other night, I was having a particularly hard time, very dark blue.

I did the now-usual up-and-down thing several times, without Molly. I finally decided to try the deck. I curled up out on the couch and settled in to mope my sad self to sleep.

A couple of minutes later, Molly came and curled up — unusually — at my chest, where she spent the night, or at least until I slept. She had decided she would force the door, and she decided the thing to do was sleep at my side, not, as she usually does, down by my feet with a foot of space between us.

So there ya go,  a simple story of a boy and his dog.

There is nothing spectacular or miraculous going on here. It’s common to almost all dogs that they’ll sit quietly and nuzzle a sad owner.

This story gives me four things to marvel at:

First, I marvel at the wonder of nature. Clearly, the body of the dog — of all dogs — is made to respond to a set of clues from the bodies around it. Stuff we’re used to calling our “emotional state” is included. (I realize I’m begging the question of my materialism here, but I don’t care: I’m a strict materialist most of the time.)

Second, I marvel at my long-term and ever-growing sense that I am not in charge of me. That is, the thing-that’s-conscious is not in any easy sense in control of the thing-that-acts. That’s a very long story and plays a part in how and what I coach.

Third, I marvel at the apparently naked-to-her-and-others intensity of my need. We cue the world constantly in ways we don’t understand and can’t see. Somehow I cued my need for what she did. Somehow she sensed and responded to that cue.

Finally, I marvel that I can think all these things without unweaving the rainbow of my affection for this little dog. Knowing we’re talking about things far beyond the control of either of us, believing they are physical and organic not mental and will-driven, in no way undermines our love, not one tot.

Pain And TDD

“We were doing TDD just like we’re supposed to, but at some point it started hurting, so we not only quit, we told everyone else on the interwebs that TDD doesn’t work.”

I met Kent Beck after a couple of years reading and writing around him, at the first ObjectMentor Extreme Programming (XP) Immersion, a wonderful week I’ll never forget, where I met so many awesome geeks and coaches. (Kent Beck, Mike Feathers, James Grenning, Bob Martin, Ron Jeffries, Martin Fowler, and more! You get the idea it was a special week?)

And Beck, answering a question, told the old Smith & Dale joke:

SMITH: Doctor, it hurts when I do this.
DALE: Don’t do that.

(The visuals include a funny wagging arm movement by Smith.)

Don’t Do That!

I chuckled. It was merely years before I grasped the deeper level of this old joke.

One might interpret it as saying “TDD hurts me, so I won’t do TDD,” but that’s actually the wrong way to interpret the joke.

You see, TDD works for some of us. And it works very well.

But it’s really important that you hear what I’m not saying.

I’m not saying that you didn’t — or aren’t — feeling pain. I’m not saying you weren’t — or aren’t — trying. I’m not saying TDD works for us because we’re smart and you’re stupid. 

What I’m saying is that you are not responding to the pain you’re feeling in the TDD way.

Pain Means Something Is Wrong

TDD is not painful.

I don’t mean that it’s not painful in the sense of “you’ll just feel a little pinch”. I mean it’s not painful at all, really.

So when we feel pain while doing TDD, something is going wrong.

The somethings that could go wrong are exactly three:

  • You are working in legacy.
  • You are learning.
  • You are working with code that needs refactoring.

That’s it. There are really no other situations where TDD should be causing pain.

Legacy Pain

TDD can leverage you out of legacy. I’ve done it. But working in legacy is just painful.

The key to successful legacy work is to become a master of extraction refactorings. Before you TDD a change, extract the change site so that it is optimal for microtesting.

When you can’t write a real microtest because of the location or accessibility or complexity, either move, extract, or simplify the code via refactorings. It’s not hard, but it’s tedious as hell, and it takes a certain boldness.

This will help. It will ease your immediate TDD pain, and it will — very gradually — lift you out of legacy work altogether.

But yeah. Legacy hurts for as long as it’s legacy, and there are not two ways about it.

Learning Pain

Most of the time, learning is a source of great joy to us. After all, we’re geeks. That’s what we do, is learn things and delight in them.

But there are some situations where learning hurts. Most of these are situations where you have to learn something while 7 people are shouting at you that if we don’t fix this we will simply all die. Let me tell you, that’s gonna hurt no matter what you do. Suggesting, of course, that we teach people not to do that.

There’s another time when it hurts. It hurts to learn when your current goal is too far over your head.

I have worked from time to time with folks with weak TDD, weak confidence, and weak knowledge of a language or a domain. That’s a painful combination.

If you are stuck at the incantation stage in a language, where you’re just barely avoiding syntax errors, and the fundamentals of the language are not yet within your grasp, it’s sore tempting to drop TDD altogether and just focus on typing the magic in correctly.

But it’s contraindicated. The reason TDD is a great design technique is because it organizes the design. That organization, plus simple extended exposure, is going to be the thing that ratchets your knowledge up most rapidly. Abandoning TDD will slow down your learning, not speed up.

Code Pain

Ahhhhhhh. Now we come to it.

I have a strong belief that code pain is the main reason people leave TDD behind.

And here’s what they’re doing wrong: gritting their teeth and trying to play through it.

That’s not the TDD way. In TDD, when we feel pain we change the code until we don’t feel it anymore. And we add what we’ve learned to our daily codesense.

Codesense isn’t one trick, it’s a thousand. And it isn’t an algorithm. Codesense comes into play at large scales and at smalls. But it all comes from feeling pain and resolving not to feel it any more.

Coming soon to a blog near you: live-action codesense examples, where pain leads to refactoring leads to new design.

We don’t play through the pain in TDD.

We use it to change our behavior & build our codesense.

Codesense: The Basis of Successful TDD

Okay, so, I’ve been a little grumpy lately.

But of course, it’s not enough to just shout at people who think TDD doesn’t work.

It must be a big weakness of our pedagogy that so many people feel that way. So I ask myself, what are we not teaching, or not teaching enough of, or not enough of us teaching?

Given the descriptions from the unfortunates who tried not-TDD under the guise of TDD, it seems clear we’ve under-emphasized the means by which the process detects flaws and forces code change.

(In one sentence, I’ll describe TDD as a process. You can go back all over this blog and to get details.  The TDD process is a matter of deciding what to change, forcing that change using one or more microtests, and concurrently optimizing the design by using your sense of the new friction, coupling, and general infelicity of the code that works.)

Wait. There it is.

Codesense Is Critical

TDD was created *by* geeks of a very high caliber. But it was created *for* all geeks, of any caliber. The result is that whole swath’s of technique have been somewhat assumed, when such assumptions were ill-warranted. To be clear, many folks have contributed much wisdom, but that wisdom is insufficiently studied and taught.

I will tell you now, as I’ve said before in the context of advocating microtests and microsteps: TDD will not work without good codesense.

Codesense is the developer’s basic sense that a given chunk of code is or isn’t optimal.

It’s how we know we’re coding well or less well.

I say the word ‘optimal’ like we’re supposed to already know that that means. The fact is there are bazillions of definitions of code optimality. Many of them capture all or part of what I mean, but others capture little or nothing.

Codesense is like common sense in three ways:

  • it’s incredibly difficult to teach;
  • once learned it seems obvious;
  • it’s noticeably uncommon.

Judgment Is The Keystone Of Codesense and of TDD

I’m gonna go off-track for a moment to make one really important point: there is no algorithm for measuring the goodness of code.

Converting codesense into mechanism is a mug’s game, but it’s been ridiculously common in the industry, and still is. There are dozens of applications you can download, buy, or liberate that purport to identify “code goodness” categorically. Some have great ideas, but they don’t really work.

If I could tell every developer — and consumer of developer services — in the world just one thing, it would be this: people write code, not computers, and that is because individual human judgment is required.

In software development, we are permanently, irrevocably, irremediably, and happily, dependent on individuals using their individual judgment.

Maybe the biggest consequence of this dependence: there are very few fixed rules in assessing code.

Codesense Changes Over Time

What rules we do have frequently change. Nothing anyone said ten years ago should be taken as for-granted truth. Nothing. The game changes too often for that.

To take a straightforward case: structured programming, and there are many many people in our field who were raised on structured programming, says that every method should have exactly one entrance and exactly one exit.

The modern synthesis is different. Nowadays we’d write this code like so:

Is the difference important? I’ll re-use a sentence I wrote nearly ten years ago:

“To a professional, *everything* counts.”

Getting Started

So, this is my first blog about codesense, but I guarantee it won’t be my last. And now that we’ve met the creature in the abstract, let’s get down to brass tacks.

Codesense is hard to teach, but it’s not that hard to learn. It starts with heightening your sensitivity to code.

I can readily recommend all of these books:

It’s important to understand: I’m not telling you to do everything these guys tell you to do. It’s not about getting an instruction book.

I’m telling you to *think* and *observe* and *notice* the code you write and what happens to it.

What’s worth noticing? What’s worth changing? How might you change it? These books and others will help you get your mind open to codesense.

Once that happens, it’s time to start looking at your daily existence as a software geek. There is no substitute for this work. The folks above are top-notch writers and thinkers about programming. They can help you learn how to judge. But the judging will still be yours.

One last thought.

Start Today, With Pain.

Notice Every Pain Code Brings You






Your Design Is Broken: It’s TDD, not TDYAR

Think about your last huge unrequited crush.

A real one, I’m talking. A crush so big you go to sleep thinking of your future together, and wake up, ummm, guilty. The kind of crush that great romantic stories are made from, and for. The wobbly-knee’d kind.

And a complete non-starter: when I say unrequited, I’m being clinical in an effort to minimize the likelihood of breaking out into laughter, as doctors and nurses in every ER around the world do.

Now, in that kind of crush, you have a vision, and that vision is glorious beyond compare. It captures entirely your ideal notions of successful love. I’m not going to ask you to describe it. In fact, please don’t describe it. I have sensitive comment readers here. But picture that imagined future, just for yourself.

Was it magnificent? Brilliant? A tale for the ages?

I’d bet it was all this and more.

In fact, there’s really only a single flaw in that entire vision.

That Future Romance Is In Your Head

That tremendous romantic vision is just that, a vision. And when it came time for that blueprint-for-love to hit the shredder we call real life, it just wasn’t up to the challenge.

Thus with your design.

You see, your design lives in your mind, like your romantic vision. Oh, it may have slightly more contact with reality, because, after all, I still can’t believe you thought that — never mind.

And, notice, I’m not suggesting you’re not the greatest software designer in known space. My point in no way depends on you being a sub-par designer. Surely, you’re not a sub-par designer of romantic visions for you, are you? Far from it.

Codeless Designs Are Relatively Worthless

A design in your head elides all messy details, tricky complications, and inevitable exceptions.

A problem your company wants to solve never does.

So how do you cope with this divergence?

You code up your design, and as the working code begins to implement the design in your head, you keep an eagle-like watch out for its inevitable infelicities, and you change the code — and your design — until it is still working and no longer has its problems.

That’s what TDD does. A sketch of a design leads to rolling some microtested working code which is re-designed in microsteps. Red. Green. Refactor. Commit.

Design-In-Head Vs. Design-In-Working-Code

When your starting design meets the emerging design that comes from repeatedly applying the TDD process, there will be clashes. Thankfully, most of them aren’t as bad as that great unrequited love. But, on the record, some of them are.

When it happens, which design is right?

The one in the working refactored microtested code is right.

Your Design Is Broken

That’s hard, but you have to let it go.

Use a mental design to work your way into the code using TDD, and your broken design will become a masterwork of productivity. Ignoring the code’s design in favor of the mind’s, and you will pay a great price, starting tomorrow and lasting until your company inevitably goes out of business.

People rail against TDD.

A great many of them are refusing to confront this basic clash of designs, and they just can’t let go of their mental construct in favor of their silicon one. (The most recent such, from the famous @DHH, reeks to me of this.)

And that explains for me a large amount of TDD criticism, and an even larger number of failed TDD adoption efforts.

If you think TDD is supposed to work w/o changing the shape of your designs, you have missed the point. It is not surprising to me that you find yourself hating TDD.

I see a lot of “TDD and my design clash, therefore TDD doesn’t work”. I’ve seen even more of it lately.

TDD Is Test Driven Development,


Test Driven “You Are Right”

One Page Intro To Microtests

A microtest has the following properties:

  • It is short, typically under a dozen lines of code.
  • It is *always* automated.
  • It does not test the object inside the running app, but instead in a purpose-built testing application.
  • It invokes only a tiny portion of the code, most usually a single branch of a single function.
  • It never *reaches* inside an object’s boundaries, though the tester may certainly *look* inside them.
  • It is coded to the same standard as shipping code, i.e. the team’s best current understanding of coding excellence.
  • It is vault-committed source, with a lifetime co-terminous with the functionality it tests.
  • In combination with all other microtests of an app, it serves as a ‘gateway-to-commit’.  A developer is encouraged to commit anytime all microtests run green.
  • It takes complete control of the object-under-test and is therefore self-contained, i.e. running with no dependencies on anything other than the testing code and its dependency graph.
  • It runs in an extremely short time, milliseconds per test.
  • It provides precise feedback on any errors that it encounters.
  • It usually (not always) runs entirely inside a single computer.
  • It usually (not always) runs entirely inside a single process, i.e. with few extra-process runtime dependencies.
  • It is part of a collection all or any subset of which can be invoked with a single programmer gesture.
  • It is written before the code-change it is meant to test.
  • It avoids most or all usage of ‘awkward’ collaborators via a variety of slip-and-fake techniques.
  • It rarely involves construction of more than a few classes of object, often one or two, usually under five.


We’re In This For The Money

(When I’m teaching and coaching, I have a number of themes that I discuss and that will show up somewhere in everything I do. Here’s the money theme, which I usually bring up at the earliest opportunity.)

Look, kids, we’re in this for the money.

Somehow you got the idea that TDD, pairing, micro-stepping, and refactoring are not about increasing your productivity.

It could be the misguided craftsmanship movement, who give you the excuse to say “we don’t have time for art.” Or maybe you heard it from nay-sayers who are against these notions from the get-go. Maybe you read stuff from the early days, when we still didn’t understand that internal quality was such a huge determinant of success. Or, worst of all, some of you heard it from people who are in favor of these ideas, but get lost in the thick of things and say stuff they really should know better than to say.

It doesn’t matter how you got the idea, though. The simple fact is it’s entirely untrue.

TDD is in every respect about increasing software development productivity.

It is not about craftsmanship or art or beauty.

It is not about being a good citizen.

It is not about taking some illusory long view instead of the short.

It is not about you being a better person.

It’s not about improving quality.

It’s about money.

Do you want to make more money? Does your company want to make more money?

There are various goals you could aim at to do that. Maybe you need to ship more quality. Maybe you need lots more features. Maybe you need a whole new approach to the problem.

Funny thing, though. No matter what your target is, or even what time-scale it lives in, you will get there faster if you are more productive.

Driving with microtests increases productivity.

The microtests do a number of things to make us faster. See my articles on how TDD works its magic, for the many cases:

  • They multiply developer intentions, which provides a powerful “online” memory.
  • They demonstrate with a flick of the wrist that a change you just made did not hurt anything.
  • Their blinding speed far exceeds any other means of feedback in utility.
  • They *force* us to work in small objects with small methods.

In a single phrase? TDD increases productivity because the hard part of programming is thinking, and they make thinking faster.

Pairing increases productivity.

This one’s been demonstrated so many times its not funny. Pairing — at a real pairing station — has the following impacts on productivity:

  • Pairs find dumb-assed syntax errors faster than solos.
  • Pairs find *shared* language for programmer intention, the most subtle and elusive part of the primary task of programming, which is understanding the code in front of you at a  glance.
  • Pairs share energy back and forth, which means they can focus on a single task for far longer than solos.
  • Pairs are more fun. (Okay, that’s not about productivity. Fine.)
  • Pairing is the most efficient mechanism for knowledge transfer.

In a single phrase? Pairing increases productivity because the hard part of programming is thinking, and they make the thinking go faster.

Refactoring increases productivity.

The reason this one’s so hard for the noobs to get is that they haven’t yet understood that the code-to-which-you-are-adding is the single biggest determinant of the speed with which you add. Continuous micro-refactoring provides these benefits to productivity:

  • They render the code-base smaller. Smaller = less to grasp. Less to grasp = faster to change.
  • They reveal intention, which is the hardest part of code-grasping. Not, “what does this code do”, but “why do we want this code to do this”.
  • They continuously improve the overall design, including performance, of the code.

So, you know, in a single phrase? Refactoring increases productivity because the hard part of programming is the thinking, and they make the thinking go faster.

Micro-stepping increases productivity.

We do all of our work, testing, designing, refactoring, really *everything*, guided by one simple question: “what’s the smallest interesting step I can take?” And we do this because micro-steps improve our productivity in these ways:

  • They mean smaller scope, meaning fewer independent concepts, meaning easier reasoning.
  • They make most bugs emerge in those same small scopes. Time debugging is dramatically reduced.
  • They provide readily testable and trackable change. Continuous change is faster than chunky change.

Oh, in a single phrase? Micro-stepping increases productivity because the hard part of programming is the thinking, and micro-stepping makes the thinking go faster.

In The Beginning…

The only time these activities slow you down is in the beginning, when — guess what — you’re still learning their basic mechanics.

Here’s the deep dark secret: working this way is not how you learned to work. How you learned to work was either on-the-job-under-the-gun or buttressed around with perfectly reasonable theories that have no bearing on actual successful practice.

Learning to work this way is hardest for skilled geeks: they have a lot more practice to unlearn. But they’ll also have the biggest productivity gains once they get it.

Step Zero? Set up a decent comfortable pairing rig and invite experts to come and play. They’ll come. Pairing is the beginning, not the end, of this technique.

Learn Your Damned Trade

Too busy to TDD?

Too busy to pair?

Too busy to refactor?

Too busy to micro-test?

I call bullshit. My buddy Erik Meade calls it Stupid Busy, and I think that nails it pretty well. All you’re really saying is that you’re too busy to go faster.

We’re In This For The Money

So Stop Screwing Around And Start Going Faster