Being Cellfish

Stuff I wished I've found in some blog (and sometimes did)

August, 2009

Change of Address
This blog has moved to blog.cellfish.se.
Posts
  • Being Cellfish

    Object Calisthenics: Rule 1: Use one level of indentation per method

    • 0 Comments

    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() 2: { 3: for (int row=0; row<rows; row++) 4: { 5: for (int column=0; column<columns; column++) 6: { 7: grid[row,column].Format(); 8: } 9: } 10: }

    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() 2: { 3: for (int row=0; row<rows; row++) 4: { 5: FormatRow(row); 6: } 7: } 8:   9: private void FormatRow(int row) 10: { 11: for (int column=0; column<columns; column++) 12: { 13: grid[row,column].Format(); 14: } 15: }

    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.

  • Being Cellfish

    Object Calisthenics: First contact

    • 1 Comments

    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:

    1. Use one level of indentation per method
    2. Don't use the else keyword
    3. Wrap all primitives and strings
    4. Use only one dot per line
    5. Don't abbreviate
    6. Keep all entities small
    7. Don't use any classes with more than two instance variables
    8. Use first class collections
    9. Don't use any getters, setters or properties

    I'll go into more detail of these nine rules over the next few days.

  • Being Cellfish

    20 tips to write a good stored procedure (is really just 12)

    • 3 Comments

    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:

    1. Capital letters for keywords and proper indentation. With todays code editors with syntax high lighting I don't see why you want to high light keywords with capital letters. The code editor will do that for you. And suggesting proper indentation is not really a tip to write a good stored procedure. It's common (coding) sense! So I don't think this one counts... Score (good-not really-bad advice IMHO): 0-1-0.
    2. Use SQL-92 syntax for joins. If MS SQL server drops support for the old syntax this is good advice. Score: 1-1-0
    3. Use as few variables as possible. The article mentions cache utilization as an argument. Sounds like premature optimization to me. I'd say use as many variables as makes sense to make the code most readable. If that turns out to be a problem, then you optimize. So in general I found this advice to be bad. Score: 1-1-1
    4. Minimize usage of dynamic queries. Kudos to the article to pointing out how to minimize the bad of dynamic queries and I guess technically minimizing could mean zero but that is really the only good advice; don't use dynamic queries. So once again a bad, or at least misleading advice IMHO. Score: 1-1-2
    5. Use fully qualified names. If you don't do this you might end up with some weird behavior so this is a good advice. Score: 2-1-2
    6. Set NOCOUNT on. Good advice: Score: 3-1-2
    7. Don't use sp_ prefix. Score: 4-1-2
    8. KEEPFIXED PLAN. Learn from this article and use it correctly. Hard to argue with "learn something and use it right". Score: 5-1-2
    9. Use select instead of set. Once again performance is mentioned as a motivator. However the potential bad side effects of using select rather than set are more important in my opinion. The problem with select is that the variable might not be set if a query returns no rows and the set gives you an error if the select returns more than one row. Read more about it here. I'd definitely prefer set over select. Score: 5-1-3
    10. Compare the right thing in the where clause. This advice just confuses me. The article talks about what operators are the fastest and then refers to this page talking about preference. Even though the article is confusing on this point the basic idea is correct. For example using IN is generally faster than NOT IN. So I'll call this one a draw. Score: 5-2-3
    11. Avoid OR in WHERE clause. This is good advise for good performance. Score: 6-2-3
    12. Use CAST over Convert. CAST is SQL92 standard. Convert is not. Score: 7-2-3
    13. Avoid distinct and order by. Once again this is common sense. Don't do things you don't need... Score: 7-3-3
    14. Avoid cursors. This falls into the same category as dynamic queries to me. The only good advice is don't use cursors. Score: 7-3-4
    15. Select only the columns you need. Common sense! Score: 7-4-4
    16. Sub queries vs joins. Article lists a few good rule of thumbs. I think you should use whatever is most readable. Score: 8-4-4
    17. Create table vs select into. Article points out important differences. Score: 9-4-4
    18. Use variables instead of temporary tables. Score: 10-4-4
    19. Use proper indexes. Score: 11-4-4
    20. Use profiler. Many tips in the article suggest you do things to improve performance. But I think doing so before you know you have a problem is a waste of time and resources. So this advice is actually one of the best advices in the article. Score: 12-4-4
  • Being Cellfish

    Remember to allocate memory just in case you run out of memory

    • 0 Comments

    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.

  • Being Cellfish

    What is a Coding Dojo?

    • 0 Comments

    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.

  • Being Cellfish

    Coding Dojo 4

    • 0 Comments

    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 2: { 3: private string input; 4: private Field field; 5:   6: public Given_a_single_1x1_fieldset_with_no_bombs() 7: { 8: input = "1 1" + Environment.NewLine + 9: "." + Environment.NewLine + 10: "0 0"; 11: field = FieldParser.Parse(input).Single(); 12: } 13:   14: [Fact] 15: public void It_should_have_one_row() 16: { 17: Assert.Equal(1, field.Rows); 18: } 19:   20: [Fact] 21: public void It_should_have_one_column() 22: { 23: Assert.Equal(1, field.Columns); 24: } 25:   26: [Fact] 27: public void It_should_have_an_empty_square_0_0() 28: { 29: Assert.False(field.IsBomb(0, 0)); 30: } 31: }
  • Being Cellfish

    How to make FxCop really ignore things you supress

    • 0 Comments

    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.

Page 2 of 2 (17 items) 12