Well, when the code is well and truly ruined,
theres just one thing to do: back it out. The
I like to think that Chet and I are pretty calm about throwing
code away. (Weve thrown away so much!) It
always hurts but only until you do it. Then
its like
Look at that code up there for SetInput. Either we have a two-pass algorithm or we have a complex setup to call a function that will be hard to write and that might still have a two-pass algorithm in it. Maybe I wasn t so wrong after all. The two-pass thing isn t as much a concern about speed, perhaps, as about our ability to express
So we imagined some new object that holds input. We called it an InputCommand, and our proposed code looks like this:
private void SetInput(StringReader reader) {
InputCommand input = InputCommand(reader);
model.Lines = input.CleanLines();
model.SelectionStart = input.SelectionStart();
If we can do something like that, it will be quite clean! So we imagine an object that will take the input from the reader that holds the whole script. It will know how to produce the clean lines (the ones without the vertical bar), and it will know how to say where the SelectionStart (cursor location) is. We think we like this. And we re pretty sure it will be easy to write. Tomorrow we re going to start on it.
|
|
If You Can t Test It, It s Wrong
When we realized we couldn t readily test this code, we should have
Procedural Code Is a Very Bad Smell
When you find yourself writing procedural methods and utility
Too Long Between Green Bars
After we made our one new unit test work, we went for a long time without a new test or a new green bar ”basically, all the time after
|
|
We messed up. We finally figured out that we had. We
The
We try always to write code that expresses our intention. (See, for example, the Test First, by Intention chapter in
Extreme Programming Installed
[Addison- Wesley, 2001].) Good code has
When we program, we all
private String[] ArrayToEnd(StringReader reader) {
ArrayList result = new ArrayList();
String line = reader.ReadLine();
while (line != null && line != "*end") {
result.Add(line.TrimEnd());
line = reader.ReadLine();
}
String[] answer = new String[result.Count]; result.CopyTo(answer);
return answer;
}
Let s figure out this code. First we build an ArrayList containing all the lines of the input StringReader, up to "*end" or the end of the reader. Then we allocate an array of Strings of the right
That code might be better if it
private String[] ArrayToEnd(StringReader reader) {
ArrayList result = ArrayListToEnd(reader);
return ArrayListToArray(result)
}
It might be even better with better names ”we could discuss that. In any case, we could argue that we should use Extract Method to refactor out those two methods, and Compose Method to create the new version of ArrayToEnd.
{% if main.adsdop %}{% include 'adsenceinline.tpl' %}{% endif %}
Programming by intention goes a step further than
Proceeding this way has a number of advantages. First, we don t have to remember so much. As soon as we know what we intend to do, we write it down. Then we just refine it until the code is there. Second, the code comes out well-
So why don t we do that all the time? We re not sure. We think it has to do with unfamiliarity with the language. We re so focused on how we might write legal statements in C#, and on which objects in C# might help us, that we forget to play our best game. Our first resolution is to return to programming by intention. Keep an eye on us, and see if we live up to our resolution.
I might not have mentioned it before, but we have a simple code manager that we use as we develop this application. It s written in Ruby, and all it does is this: whenever we type
cm
in a command window, all the files of the source directory are
You re probably asking yourself, if they used this cm thing, why did they have to Ctrl+Z
That was today s second resolution: have more points to back up to. That will make it easier to back up when we make a mistake, and we ll be less encouraged to keep plunging on, deeper and deeper into the depths of coding depravity.