First of all a method with a lot of different indentation is harder to understand than a method with less indentation. I also think that each level of indentation typically means you're doing another thing. Look at this code:
1: public void Format()
3: for (int row=0; row<rows; row++)
5: for (int column=0; column<columns; column++)
The nested for loop introduces two levels of indentation. One of them can be refactored into a second method so it looks like this:
1: public void Format()
3: for (int row=0; row<rows; row++)
9: private void FormatRow(int row)
11: for (int column=0; column<columns; column++)
Some people might say that it is just another level of indirection and that we have now made the Format method harder to understand since we also have to look in the FormatRow method to understand what is happening. I think that is only true if you use bad method names I'm perfectly fine with assuming that FormatRow actually formats a row without looking at the code for FormatRow. So if extracting code to a separate method will make your code less readable you're probably not giving the method a very good name.
Some people also scream that more methods means bad performance. First; believe in the compilers ability to optimize code for you. Second; only optimize what is proved to be a bottleneck. I think readability is preferred over any theoretical performance issue. Only real performance issues should be addressed.
Last but not least, this rule is not intended to be used in your production code. We're talking object calisthenics, remember? If you want to apply this rule to your real code you probably want to say use as few levels of indentations as possible in each method.
A few weeks ago I was introduced the the object calisthenics described by Jeff Bay in the book The ThoughtWorks Anthology. The object calisthenics is a way to practice writing object oriented code. The nine rules of are not intended to be used in your every day work. The rules are intended to be used on a small problem such as a coding Kata. The idea is that by applying these strict rules on a small problem you'll learn to write better code.
So I decided to try this on the MineSweeper Kata. In the beginning I decided to try to conform to the rules all the time, but pretty soon I changed my mind and wrote a working solution and then started to refactored to conform to the rules. I think this was a mistake. Some design decisions turned out to require very big refactorings when conforming to the rules and I actually never got all the way. But this doesn't mean I didn't learn anything. First of all I think I experienced a variant of you can't test in quality, you have to build it in from the start. I should have stuck with the initial strategy and make sure the code followed the rules all the time. I also learned that classes that I felt were really small and doing only one thing actually could be split up when I had to in order to conform to the rules. Reminds me of when people thought atoms were the smallest building blocks of the universe and then it turned out to be something smaller...
So all in all I think doing a coding Kata while applying the object calisthenics rules will improve my ability to write object oriented code. And it will be interesting to see how it works out in a coding dojo. By now you're probably wondering what the nine rules are. The rules are:
I'll go into more detail of these nine rules over the next few days.
A few days ago there was an article with 20 tips to write a good stored procedure (requires free registration to read). The problem is that there are really only 12 good tips (and 4 bad and 4 neither good or bad). So let me go over the tips one by one and comment on them:
Today I read this blog post about how all .Net applications create three exceptions upon start; System.ExecutionEngineException, System.StackOverflowException and System.OutOfMemoryException. The reason is that if these are not allocated from the start, they cannot be created when they occur. This reminded me of when I was writing high performance daemons in C a few years ago.
In those daemons I did a number of things to prepare for the event of memory starvation. First of all I allocated some memory (a few Kb if I remember correctly). If the daemon ran out of memory it was suspended for up to a second and the memory allocation was tried again. Typically I did a handful of retries and if they all failed I released the preallocated memory, logged the error and terminated the process.
The reasoning behind this strategy was based on three assumptions. First of all, if a process cannot allocate memory it is because some other process is leaking memory (or is just using a lot of memory). Second assumption is that the offending process will terminate fairly quickly because of this. Last assumption is that if the offending process does not release memory quick enough it might be the current process that is the problem so it must terminate to let other processes proceed normally. But before termination we release some preallocated memory so that we have enough memory to log the problem.
So what about multi-threaded daemons? If one thread releases some memory another might take it all before we get the chance to log the problem. Well, in my case all daemons were single threaded. If I needed "threads" (which was rare) I forked. So that was not a problem I had to consider.
I've heard that some people don't think the CodingDojo site tells you a lot about what to expect in a coding dojo. It's more about practical things and listing a number of good problems to solve during the dojo. So I'll try to elaborate. In a coding dojo you will learn something. It might be TDD if you don't know a lot about it or it might be some smart trick in the development environment. You will also learn something about how others write their code. You will learn this since a typical dojo is setup with one computer desktop projected on the wall and all participants takes turns at the keyboard. You should not be intimidated by the fact that you will code in front of others for a few minutes. People attending dojos typically like to teach and learn so you will get help from the group.
You should not expect to see the announced problem being solved. In my experience it is very rare that a dojo ends with a complete solution. And completing is not the goal. Learning along the way is the important thing. A coding dojo is a safe environment where you can try new ideas and make mistakes without putting your real work at risk. A coding dojo is also a great opportunity to improve your development skills.
A typical dojo starts with a short introduction to the environment and a short design discussion. In most dojos two people then starts coding as a pair. After a few minutes (typically around five) one person in the pair gets substituted by somebody else in the group and so on. Even though the person at the keyboard is in command, the whole group typically participates giving suggestions on what to do. If more discussion is needed, that is done without stopping the timer counting down to the next switch. The dojo ends with a retrospect so that the dojo can be improved to the next time.
Fourth MSFTCorpDojo today. MineSweeper and MicroPairing this time too.This time we, as a result of the retrospect from last time, we did BDD-style testing (I've added one of the test classes below as an example). We decided to start by implementing a parser that parsed the input and created an internal representation of the input that we could later use to generate the output. By the end of the session we had a pretty complete parser with error handling for all kinds of bad input. This is one of the few times I've seen any real error handling in a dojo.
This time in the retrospect we said that the next time we should implement the other part next time. That is; assume a parsed input in some internal representation and generate the output from that. We also talked about how we do MicroPairing and switch one person in the pair every seven minutes. We decided to next time switch one person in the pair every time the keyboard gets passed instead. Guess that will mean less pair programming since there is no real ping-pong but rather a circular queue. But in our session almost everybody participates all the time anyway so that might not necessarily be a problem.
1: public class Given_a_single_1x1_fieldset_with_no_bombs
3: private string input;
4: private Field field;
6: public Given_a_single_1x1_fieldset_with_no_bombs()
8: input = "1 1" + Environment.NewLine +
9: "." + Environment.NewLine +
10: "0 0";
11: field = FieldParser.Parse(input).Single();
15: public void It_should_have_one_row()
17: Assert.Equal(1, field.Rows);
21: public void It_should_have_one_column()
23: Assert.Equal(1, field.Columns);
27: public void It_should_have_an_empty_square_0_0()
29: Assert.False(field.IsBomb(0, 0));
I recently experienced a weird behavior with FxCop. The classical "everything works fine on my machine but not on the build server" situation. In this case I got a few FxCop warnings from the build server but could not replicate when I ran FxCop locally in Visual Studio. Turns out I had to turn on code analysis in the build (Project properties -> code analysis) since the FxCop suppress attributes used to suppress warnings on specific methods are conditional attributes. More on the background here.