Ward Cunningham posted a video on Technical Debt, and Kent Beck and Ed Yourdan (and I) have been tweeting about it. Let me share some thoughts with you here.
In Ward’s video, he refers to some folks’ notion that is is OK to write the program a little less well with intention to clean it up later. He’s not in favor of that. He says that the program as written should always reflect all of our understanding of the problem and the solution, as of the time we wrote it.
Ward points out that as time passes, our understanding will move beyond the design as reflected in the code. This amounts to “interest due” on the code, and if too much interest comes due, you will be unable to make much real progress, just as when our credit card debt gets too high, we have no money left to actually buy anything.
Meanwhile, Kent and Ed were tweeting about transparency, and Kent gave the example that “many people argue that customers e.g. ‘don’t need to know” about refactoring.'” My purpose here is to talk about when customers do need to know … and when they don’t.
In one sense, the customers always need to know. Something like this:
Hi Customer. Producing stories at a reasonable and essentially constant rate requires that the code be kept in good order. The grubbier the code, the slower we go. Therefore, the professional thing to do is to keep the code in the good range. We do this by continuous refactoring. It is part of our responsibility to you and is part of developing software for you. We promise to do it.
With that understanding in place, we need not track specific time spent refactoring. In fact, we probably shouldn’t even be able to track it: we will ideally move so smoothly and rapidly between refactoring and testing and coding and designing that we can’t keep track of the time.
However, as a program evolves, there’s a good chance that the Design In Code will not include all the good things we now understand. We have a better Design In Head. When the design in our head is enough better than the one in the code, it can pay off to bring the code closer to what we now understand.
One way to do that is to tell the customer — the topic of the Beck/Yourdon/Jeffries tweets.
Hi, Customer. We have some new understanding of good ways to build a program like ours, and if we put some of that in, at a cost of N days, we should be able to speed up our development by Y percent. What do you think?
Note that this conversation really needs to include the cost (N days) and the benefit (Y percent). If we can’t give this information, how can the customer possibly make a good decision?
Even if do we provide this information, what will the customer choose? Well, the customer wants features. Features today, features tomorrow, features every day. Features now very likely seem better than some higher fraction of features at some future time. So the customer is likely to want to defer the refactoring, especially since it isn’t really necessary. So they may say “later”, or they may ask if we could just do a little bit each week.
When a team finds itself wanting to ask permission to do some big refactoring, I see that as a danger signal. Two danger signals, in fact:
- We have failed to notice a deviation between what we know and what we have expressed in the code for long enough to let the deviation get large.
- The best way we can think of to fix the problem is to get everyone out of the pool and refactor like demons.
Well, if that’s the best we can do, we have a responsibility to open the question with our customer, because there is an important and major monetary decision to be made. Should we leave the road deteriorating and experience continuing slowdowns, or should we stop, resurface the road, and then get traffic going again?
However, that’s not the best we might possibly do. Remember what we said at the beginning?
Producing stories at a reasonable and essentially constant rate requires that the code be kept in good order. The grubbier the code, the slower we go. Therefore, the professional thing to do is to keep the code in the good range. We do this by continuous refactoring. It is part of our responsibility to you and is part of developing software for you. We promise to do it.
OK, then. We see a new design that we wish we had. We refactor the code daily because it is part of our promise. Let’s figure out how to morph the code from where it is, to where it needs to be, in the same way we always do it, incrementally, inch by inch, step by step (slowly I turned). If we can do that, we won’t need to ask permission to clean things up.
Can every refactoring be done inch by inch, step by step (slowly I turned)? Well, yes. Do I know how to do every one? Well, no. What I do know, however, is that by the time I have finished doing one as a blob, I have always then known how I could have done it incrementally. So I conclude that I have some learnin’ to do … but that it is always possible.
So we don’t have to tell?
Sorry. We do have to tell, because we want everyone on the team, including the customer, to know what is going on. We just don’t have to ask permission.
As I worked on Story Abra and Story Kazam, I ran across some of that code that uses the old Bungle object, so I refactored it to use the new Fangle object. When I was done, I searched for remaining uses of Bungle and there are only 31 to go. That’s down from 137. Yay, us!