You’d think that software developers would realize that they are prone to error. Yet we are often more opinionated than we probably should be. Here’s my opinion on that.
Perhaps my most famous article is We Tried Baseball and It Didn’t Work.
Welcome back. The other day, hearing one of my colleagues bemoaning the fact that so many conversations find someone saying something like “Object-Oriented has failed” or “TDD has failed” or “Scrum has failed”. I subtweeted:
I know the source of my failures, and it’s not a paradigm or process. You may quote me.
It has been my experience that sometimes bad things happen to me. It has always seemed to me that one can just accept that sometimes bad things happen to good people and move on, secure in the notion that one is just fine, or that one can look at the things one has done to see whether any of them may have had some part in causing the bad thing, or whether there might be things to do in the future to decrease the chances of bad things happening.
My personality evolved in a way that left me far more inclined to think and act as if I had substantial influence over what happened to me, and that led me to try to learn ways of acting that tend to bring more good things and fewer bad ones.
That’s not to say that I believe that we can control everything. On the contrary, I think that life is a lot like floating in a rubber raft, down the Youghiogheny River in Ohiopyle, Pennsylvania. You’ll pretty much go where the river wants you to go.
And yet. And yet. You’ll find that while all your paddling won’t get you quite where you want to go, you can influence what happens, often rather strongly. You can probably keep yourself from tipping over. You can almost always keep the front of the raft pointed downstream.
And then … and then … you notice the guides in their kayaks, holding dead still in the water, seemingly only stirring a bit with their paddle. They seem almost uninfluenced by the same water that’s tossing you all over.
On the river, it matters how you paddle. And it matters what kind of boat you have. Oh, you’ll still probably go downstream and sometimes you’ll probably find yourself in the water, and you can be sure you’ll be wet all over. But it does matter how you paddle.
What Does This Have to Do With Anything?
Well, the first thing, where I started, was attitude. I choose to behave as though I have influence over what happens to me. So when I encounter failure1, I look at the past to see where I may have misstepped, and I look to the future to see what I might do better next time.
I assume that what I do makes a difference. I can’t imagine living with the alternative view, that what I do doesn’t matter. That would be horrible.
Let’s look at programming for a while.
What would it mean for TDD to fail? I guess we’d have to see what TDD promises to do. I think it would be something like this:
TDD leads to simple design and to high confidence that the program does what we expect it to do.
I don’t think we’d claim that TDD eliminates all defects, even though some teams have literally reduced their defect insertion rate by two orders of magnitude using TDD and other practices.
I don’t think we’d claim that using TDD you are guaranteed a perfect, or even really good design, even though when you watch a TDD expert producing software, they may produce truly lovely simple designs.
I don’t think we’d claim that TDD guarantees anything, even though we are often quite enthusiastic about the results we get.
And I’m sure we’d never claim that TDD can be used in a rote mindless way to any benefit.
Still, suppose Alex Coder tries TDD and does not come out with a simple design, and does not have high confidence in the code. Suppose Alex says “TDD failed. I didn’t get a simple design and I didn’t get high confidence. In fact the TDD program was hideous and bug-ridden.”
I think that if we were to ask Alex a few more questions, we would get some interesting answers. For example, if we were to ask how easy or hard it was to write the tests, I’d wager that Alex would tell us that it was difficult, often very difficult, to write tests. If we were to ask how often tests needed to be changed, Alex would very likely tell us that they had to change many tests very often, to the point where keeping all the tests running was more work than the actual program.
We would be sorely tempted to say “You were doing it wrong”. Soon enough someone would be shouting “No true Scotsman!”
Who’s right? Who’s wrong? Well, yes. I have come to believe something like this about TDD:
TDD works nicely when the developer favors small cohesive objects and methods, so that most functions are isolated and independent. It works particularly well when objects are immutable, or when state changes are small and discrete. It works well with a “tell, don’t ask” style of development.
TDD does not work well when the developer favors large flowing functions that tell a whole story in detail. It doesn’t work well when objects are caused to change state often. It doesn’t work so well with large objects with many members changing independently.
Now it is “well known” that small cohesive objects and procedures are “better” than long rambling methods and massive objects that combine everything there is to know about the universe. By “well known”, I mean something a bit stronger than “Well, Ron and Kent like it”, but certainly weaker than “No one can possibly succeed with large objects and highly procedural code”.
Taking the value judgement out of the equation, I would say that TDD works well with highly cohesive, loosely connected objects and small functions, and not with objects that have low cohesion and high coupling, nor with large functions.
Does TDD “fail” under those circumstances? I don’t know. Does a hammer fail when you try to drive a screw with it?
We can move more quickly to OO. When does Object Oriented programming fail?
It will certainly not provide much benefit if you prefer one huge class that contains all the data you have to deal with, and all the code that ever needs to manipulate any of the data in there, all in one giant method.
Oddly enough, OO works best in the same circumstances as TDD: when the code you write is highly modular, very cohesive, with small functions and objects.
Does OO fail when you prefer large functions operating on giant blobs of data? Does a weed whacker fail when you try to cut down an oak tree with it?
When someone says “Scrum failed”, we need more information. In what way did Scrum “fail”?
- Did your project not come in on time and on budget?
- Did you not get twice the work in half the time?
- Did you, in your role, hate it?
Scrum, if you actually study it even a little bit, is quite explicit about the conditions that need to be in place. It starts with values:
Successful use of Scrum depends on people becoming more proficient in living five values:
Commitment, Focus, Openness, Respect, and Courage
If I were to encounter a so-called Scrum effort where people were not living those values, I’d be inclined to blow my whistle and flag a serious problem.
Scrum requires that the “Product Owner” put the work in priority order into a list called the Backlog.
Accordingly, if we encounter a so-called Scrum effort with no Product Owner, or without an ordered list of things to do, or when the list changes daily, we have to ask whether this is really Scrum at all.
If they simply must work that way, we have to suggest that Scrum is not something they should do. It’s not something they even could do.
Scrum requires that the Scrum Team selects how much work to do in each Sprint.
If in a so-called Scrum effort we find some person who tells the team what they must work on and how much work they must produce, that’s not really Scrum at all.
If that’s how you’re going to manage the work, Scrum is not for you. You can’t do Scrum that way.
Scrum requires that the team produce a working tested increment of code in each Sprint.
If on some so-called Scrum effort, the team is not producing working software every Sprint, I humbly beg your pardon, but they are not yet doing Scrum. The next rule applies: you have to figure out what’s wrong2 and fix it.
If you’re going to do your effort without building working software in every Sprint, Scrum is not for you. You can’t do Scrum that way.
Scrum requires that the team and stakeholders inspect the results and adjust how they work for the next Sprint.
If on some so-called Scrum effort, the same problems occur Sprint after Sprint and effective changes are not put in place to resolve the problems, there are only two possibilities.
Most likely, they’re not really trying to fix them. Maybe the group doesn’t have enough openness, respect, and courage to even bring them up. Maybe someone in power has demanded that people just try harder. One way or another, they’re choosing not to fix them.
It is barely possible that the problems cannot be fixed.
In either case, Scrum has done its job, identifying the problems. Whether they choose not to fix them, or simply cannot fix them. Scrum’s job here is done.
Mind You …
I’m not saying Scrum is perfect. I’m not even saying it is good. I am saying that it is absolutely explicit about what it requires you to do, and about what it promises3, which is to identify problems for you to solve.
If you do Scrum adequately, I think you’re likely to benefit. And, if you do it better than adequately, I think you’ll evolve beyond it to something even better.
As a software developer, you should know that you are quite frequently wrong. As a human, you should know that you are quite frequently wrong.
When things don’t go your way, you can blame OO, or TDD, or Scrum, or the Universe, or you can think about what is going on and see whether you can paddle a bit differently. Maybe you even need a new boat.
Or just float downstream. That’s OK. It’s your4 choice.
I would have said “When I fail”, but I’m trying to be gentle, and to entrap readers who personally never fail, but only “encounter failure”. ↩
Curiously enough, part of what’s wrong is quite likely that they’re not doing TDD, refactoring, and the other XP practices that seem to be all but necessary in order to do iterative incremental software development. ↩
Except for that odious “twice the work in half the time”. Yes, if you have an ordinary team and you manage to do Scrum well, you will very likely see much higher productivity. But the title … that’s razor blades to babies. ↩
As frequent readers know, I rarely say “you”, preferring “we”. Here, the “you” seemed necessary. I apologize if that troubles, um, you. ↩