Motivation for one-line methods
A simple thing that I often do to clean up and improve code as I am trying to understand it is to extract short fragments of a method into a new, smaller method. Quite often I will move just a single line of code into a new method. The reason for doing this is of course to document why the line exists by naming the method accordingly. However, even though more and more people are now realizing that comments are a code smell, I am sometimes challenged to provide a motivation for extracting it into a method instead of simply writing a comment for that one line of code.
Take a look at the code fragment below:
public void readSomeData(int x, int y) {
int position = x / y - this.z;
startReadingFromPosition(position);
}
That first line of code calculates a value according to some rules that are not quite clear from just seeing it. Lets say that this specific calculation is called the UltraMegaAlgorithm. Naturally we need to document this to help readers know that we use this algorithm. But why not simply write a comment? What is the difference between the two alternatives below?
public void readSomeData(int x, int y) {
// Use UltraMegaAlgorithm to calculate starting position
int position = x / y - this.z;
startReadingFromPosition(position);
}
/* -------------------- */
public void readSomeData(int x, int y) {
int position =
calculateStartingPositionUsingUltraMegaAlgorithm(x, y);
startReadingFromPosition(position);
}
private int calculateStartingPositionUsingUltraMegaAlgorithm(
int x, int y) {
return x / y - this.z;
}
Some will argue that it is much easier to read the comment than the camelCased method name. And I agree, it is really unfortunate that method names are often written this way (I think Ruby’s calculate_starting_position_using_ultra_mega_algorithm is at least better, but it is difficult to get Java and .Net programmers to change their old policies). But I would still argue that the second alternative is better. I could argue that we might want to do more than simply extracting into a new method. Perhaps we want to Move Method into another class. Perhaps this might become a strategy implementation. But I think there is a much simpler reason.
My main motivation for extracting into a method lies in considering what is important to us when we read the code to try and understand it. We want to see that readSomeData uses the UltraMegaAlgorithm to calculate a starting position, and then starts (doing whatever it does) from that position. We are completely oblivious to how the UltraMegaAlgorithm is implemented! The information in the comment is what is interesting to us here, not the implementation following it. In fact, that line makes it harder to understand what readSomeData does, since we will stop to consider the implementation even if we do not want to.
My rule of thumb is that the steps of a non-private method should be easy to understand by simply glancing at it. The way to achieve this is to make it read like normal language, which means that unclear one-liners with comments should be replaced with a method call that hides the implementation that the comment describes the reason for. If I trust the implementation of calculateStartingPositionUsingUltraMegaAlgorithm to be correct I can decide for myself if I just need to know that the code does this, of if I want to drill down and learn about the implementation as well.
Real Retrospectives - Not Just Talking
Last Thursday, me and my colleague Andrés Taylor ran a session at Cornerstone’s Developer Summit 2008 in Stockholm. The title was Real Retrospectives - Not Just Talking. Our main point was that retrospectives are a great way of helping the team define (and refine) their own process, one that they agree on and will commit to working with. However, it is not as easy as sitting down around a table for a quick chat (more on this in a later post). To have an effective group discussion you need a structure that supports it.
In fact, with inspiration from Lawrence Lessig, we tried to condense our entire presentation into a short "refrain" (if our presentation would have been a song):
We have to constantly adapt our method to our current reality.
To adapt our method effectively, we have to think together.
Thinking together is hard, and requires focused effort.
We showed these lines several times throughout the presentation, sometimes reading them out loud, sometimes just flashing through them. And as we ended the presentation by showing the refrain a final time we also read it together which produced a few laughs. I think this worked very well and hopefully will help the audience to remember our message. All credits to Andrés for suggesting this and convincing me that it would work.
Our slides and also some pointers to further reading material are available at Blueplane’s web site. The site is in Swedish, but just look for Real Retrospectives and the links in that section. However, I do not think that the slides will be of much value if you did not attend the presentation, so I will try and cover some of what we said in future blog posts (and I am sure Andrés will do the same).
Regarding the conference, I was very happy to see a track called People Matters Too! at a very much developer oriented conference. I was even more happy to see so many people turn up for our session as well as the other sessions in this track. I am sure this will continue next year with at least a full day track like this one. See you there!
Sharing
Late friday evening, after some wine, whisky and beer and a movie, I could not think of anything better to do than to catch up a bit on my blog reading (it’s not just my posting that is more or less dead right now, parental leave has left a lot of unread items in Google Reader). After reading a couple of hundred posts, in the end it was two that really stuck in my head. Maybe it was just the short and simple format of them that made it easier to read them, but they really spoke to me.
I used to have the latin phrase Docendo discimus (We learn by teaching) as my personal motto, but I think Jason Yip really nails it with:
Jason says you should always explain why, especially to children and others who really have no idea why something happens the way it does. Never just say it’s magic or so. I couldn’t agree more.
On a somewhat similar note, Paul Duvall discuss why you should fire your best people … reward the lazy ones. Now, the title is of course a bit misleading although there is some truth to it, but the message of the post for me can be boiled down to the following quote from the post:
If the knowledge is locked in your head, you are a less valuable, not more valuable, resource.
To me, these posts say that it is always important to take the time to share the knowledge instead of just “making it so”, whether it is something we implement in software or just something we say to someone.
Programming with your nose
While flipping through an old MSDN magazine* today, I was inspired to this thought: Programming is done with the nose! One way of describing programming as using your nose would be to refer to the analogy of code smells. While I have always liked that analogy, that was however not what I had in mind here.
The article that inspired my thought was Stan Lippman’s column entitled Is Programming an Art?, where he compares software development to art. I like calling software development an art, in the same way as the process of creating a Scotch Blended Whisky is often called an art (as opposed to creating malt whisky which is called a science, since it is mostly about following a protocol). When creating a blended whisky, the Master Blender will use nothing but his nose to select the combination of malt and grain whisky to include in the blend. Sometimes a blend will include up to 50 different sorts of whisky. And every batch of blended whisky that is produced must consistently taste and smell the same way. Anyone interested in Single Malts knows that whisky from different batches, even different barrels in the same batch, will have different characteristics, so being a “Noser” (which is a much cooler title than Master Blender) is truly a difficult job with no easy way of simply following a protocol.
This art of “nosing” in many ways remind me of creating software. Although many would like it to be, software development is not about following a simple process of pressing a couple of buttons and drawing some lines. Producing software requires coding, and no project is ever the same as another one.
Here’s another thought: Maybe this means we can finally retire the term Architect? Lets start using Noser instead, at least for architects doing real work. :D
*Ironically, this was right after I had listened to Don Box and Chris Sells on .NET Rocks!, talking about how no one actually reads magazines anymore and they could not remember when the last time they saw a copy of MSDN magazine was. I think that was the main reason I picked it up and browsed through it. :)
Will it be C#?
In More Ruby-Influenced BDD in .NET, Scott Bellware writes:
I’m not sure that C# will ultimately the language that will let BDD really shine on the CLR. Without some kind of DSL ability like what can be had from Ruby and Boo, it’s kinda hard to conceive of specification syntaxes that won’t be fraught with C# line noise.
Here is a thought I had while reading this: Is C# ultimately the language we will use on the CLR, period? (VB guys, substitute C# for VB.NET if you want)
Or, to put it in another way, which has the longest lifetime, C# or the CLR platform? For instance, on the Java side of things, here are two slides from Polyglot Programming, a presentation by Neal Ford:
Another language will supplant Java as the primary way people code the Java Platform
Start treating Java as the assembly language of the Java Platform
In the future, will C# be the primary way of programming the .NET platform?
Don’t blame Paula!
I used to subscribe to the blog Worse Than Failure (formerly The Daily WTF), but it got removed when I was trimming the number of blogs in my reader. If you have not seen it, they post examples of code that is really badly written or designed. Most often there is also a funny story to go with the code. One of the most absurd posts that I remember was one called The Brillant Paula Bean.
It is a very short post, so go read it if you want. For the even shorter summary, it tells the story of a company that brought in a contractor, Paula, to help with a Java project. She was apparently handed some work to do, and for a few months she reported good progress during the weekly status meetings. However when the deadline came closer she asked for some help to finish it in time, and then it became clear that all she had produced was a couple lines of code that could do nothing more than return a misspelled string.
I guess all posts at WTF has to be taken with a grain of salt, but for now let us consider this one to actually be true. Like I said, it is really absurd, but what is it actually that is most absurd here? While there is no question that Paula was not a very good programmer, can we really blame her for this mess? If the story is true, this is clearly an example of a process problem. Why did no one notice there were no commits from her? Why did no one review her code? How did she ever get hired? There are so many ways this mess could have been avoided. For instance if Paula would have been pair-programming, her lack of skills would have been noticed at day one. With smaller tasks it would have been clear that she where having problems much earlier.
Unfortunately, even if the story turns out to be untrue, I do not think it is that uncommon. Change a few of the extremes of the story (the ridiculously low amount of code produced, the quite long time period, the insanely large task she must have been working on to be given so much time) into more realistic ones and I think most of us will recognise situations that we have been in. Maybe not situations that ended up the same way, but definitely situations that had the potential to do so. Things such as not testing the code and application enough, not having code reviews, and working on too large tasks with individual responsibility for the programmer that is given them all have the potential to end up in disasters such as The Brillant Paula Bean. When they do, instead of just pointing fingers at the person who screwed up, ask how it happened. Find out what is the root cause and eliminate it.
Ruby-style iterations in C# 3.0
While Ruby does have a for-loop, it is not commonly used in idiomatic Ruby code. Instead, to loop a number of times and do something in each run you would write code like this:
5.times do |i| print i end # equivalent for loop over a range for int i in 0...5 print i end
I do not know about you, but I definitely like the 5.times way better. With the new C# 3.0 (as part of Linq) feature extension methods it is a trivial thing to make it possible to write very similar code in C#:
// using a lambda function, also a C# 3.0 feature
5.Times( i => Console.WriteLine(i) );
// or using a "simple" C# 2.0 delegate
5.Times(delegate (int i)
{
Console.WriteLine(i);
});
So how does this work? By creating an extension method for int and bringing that into scope (with a using statement) all ints will now be extended with the method Times. Actually, int has of course not really been modified “on the fly” to include a new method, it is really only syntactic sugar for a method call such as IntExtensions.Times(5, i => Console.WriteLine(i));. Here is the simple extension method:
public static class IntExtensions
{
public static void Times(this int count, Action<int> block)
{
for (int i = 0; i < count; i++)
{
block.Invoke(i);
}
}
}
So what do you think? Am I crazy for even thinking about writing my C# (3.0) code in this way? Would you get confused and angry by looking at the code?
Freedom fosters responsibility
Take a look at the photo to the right. Notice anything specific about it? Here is a hint: think about enforcing rules. See it now? That is right, there are no lanes, road signs, pedestrian crossings or similar. Other than the give-way markings on the ground, the intersection is completely clear of anything that rules how you should act here.
The photo shows a “traffic calmed” roundabout in the city of Drachten, Holland. Most of the city centre is actually completely free of the traffic ruling items mentioned above. But does this not lead to a lot of incidents? Surely there is some meaning behind this idea, but how can this possibly work? The simple answer is that the lack of road signs and such leads people to such a crazy thing as to actually take eye contact with each other. Instead of taking an “I have the right to do this”-attitude, people actually take responsibility and work together to avoid incidents. How many accidents involving cars and pedestrians are not the result the pedestrian simply walking straight out onto a pedestrian crossing expecting any cars to stop. The fact that there is a sign that says it is a pedestrian crossing combined with a law that says cars should stop for pedestrians does not mean that every car will automatically stop! The only thing that this really means is that cars have a responsibility to stop for pedestrians, but pedestrians do not have a right to walk right out into the street.
Although I know analogies can be dangerous, the reason I mention this is that I came to think about it after having a discussion over lunch regarding programming languages and how the code turns out in different ones. The discussion started with Martin talking about how he writes better code in C++ than he does when using C#. And I can vouch for his abilities in both languages, so it is not as simple as that. The reason, he said, was that C++ was more complex than C# and it is easier to get things wrong, so therefore he paid more attention to what he does when coding in C++. Instead of relying on the (sometimes dubiously) safe environment to help you, taking a step back to actually think for a second or two and make sure that what you just wrote not only solves whatever it should but is also meaningful to someone reading it later makes a huge difference.
The fears and skepticism people have about the lack of road signs in the Drachten intersections can be noted when developers skeptic to dynamic languages describe how they feel about them. “Does not the lack of structure make people do all sorts of crazy things? If someone can just open up a class at any time and modify a method (or add new ones), how can it possibly work out in a collaborative environment such as a typical software development project?” For the same reasons as the Drachten intersections lead to fewer accidents. By removing the “secure” environment of compile-time checking, people are actually forced to think and talk to eachother. Developers use better names for classes and methods, and also use tests to specify their intentions, both to the test runner and to other developers.
I want to use one last example. One practice common in agile development (and elsewhere of course) is continuous integration (CI). The idea is simple, integrate whenever any changes to the system are saved. Unfortunately it is also quite common to see this interpreted as “set up some CI server software, then we are done”. While a CI server can definitely be of use, people forget that CI is really just an attitude and has nothing to do with having a CI server. The CI server becomes the road signs of the intersection. Instead of thinking in terms of what your responsibilities are when checking in, you trust the CI server to solve all problems for you.
To summarize: Be sure to not allow yourself or your team to get a false sense of security from processes and rules. Instead focus on the social parts of software development. Individuals and interactions over processes and tools is what it is all about.
–
Photo downloaded from sociate’s flickr account, used under a Creative Commons Attribution-ShareAlike 2.0 license.
Testing events with unit tests
How to test events seem to be a question that sometimes comes up regarding unit testing. There are three different things that we want to test when using events.
* Verify that an event subscriber really wires up a listener to an event
* Verify that an event subscriber does what it should when that event is fired
* Verify that an event publisher fires an event when it should
The first two are basically the same. If we can verify that some action that should be taken when an event is fired really does happen then we have of course also verified that the subscriber does listen to the event. But I prefer to start simple with my tests and therefore often end up with a small test like the following one for testing the wiring only:
using System;
using NUnit.Framework;
namespace TestingEvents
{
[TestFixtureAttribute]
public class EventsFiringTests
{
[Test]
public void SubscriberWiresListenerToListenToMeEvent()
{
FakePublisher publisher = new FakePublisher();
new SubscriberUnderTest(publisher);
Assert.AreEqual(1, publisher.ListenToMeSubscriberCount);
}
}
public interface Publisher
{
event EventHandler ListenToMe;
}
public class FakePublisher : Publisher
{
public event EventHandler ListenToMe;
public int ListenToMeSubscriberCount
{
get { return ListenToMe.GetInvocationList().Length; }
}
public void FireListenToMe()
{
ListenToMe.Invoke(this, EventArgs.Empty);
}
}
public class SubscriberUnderTest
{
private string message;
public SubscriberUnderTest(Publisher publisher)
{
message = null;
publisher.ListenToMe += IAmListening;
}
private void IAmListening(object sender, EventArgs args)
{
message = "I heard that!";
}
public string Message
{
get { return message; }
}
}
}
This test only tests that the subscriber actually does wire up a listener to the ListenToMe event of the publisher it is instantiated with. The next step is to verify what it does when the event is fired from the publisher. The next test takes care of that.
[Test]
public void MessageIsSetWhenListenToMeIsFired()
{
FakePublisher publisher = new FakePublisher();
SubscriberUnderTest subscriber = new SubscriberUnderTest(publisher);
publisher.FireListenToMe();
Assert.AreEqual("I heard that!", subscriber.Message);
}
That takes care of testing that a subscriber does what we expect it to when the event it subscribes to is fired. The final thing that needs to be tested is that a publisher actually fires an event when we expect it to. Lets add a new class, PublisherUnderTest, and another test.
[Test]
public void PublisherFiresListenToMeWhenAngry()
{
PublisherUnderTest publisher = new PublisherUnderTest();
bool listenToMeWasCalled = false;
publisher.ListenToMe += delegate { listenToMeWasCalled = true; };
Assert.AreEqual(true, listenToMeWasCalled);
}
public class PublisherUnderTest : Publisher
{
public event EventHandler ListenToMe;
public void GetAngry()
{
if (ListenToMe != null)
{
ListenToMe.Invoke(this, EventArgs.Empty);
}
}
}
The test simply assigns an anonymous method to listen to the event from the publisher. In the anonymous method a boolean value is set to true to indicate that the event was fired.
Back from SQL Server Open World 2007
From thursday evening until saturday afternoon I was at the SQL Server Open World in Denmark. SSOW turned out to be an excellent conference. There where about 140 attendees and speakers and there was a lot of interaction between people. Networking is always important and of course happens at all conferences, but I do believe that SSOW had a couple of things helping make networking very easy. How about these examples?
- During the first evening after the opening introduction and “technical” presentation they moved everyone into “the party house”. This was where the unfortunate latest employees of Miracle (the conference organizers) happened to live. Note that everyone means about a hundred people, in one small house meant for 4-8 people.
- The party house had free beer, brewed by Miracle themselves (or rather their sister company that is in the beer brewing business).
- Friday night was beach party. The conference was held at Lallandia, a vacation resort in Denmark with a big indoors waterland. Networking is just so much easier in a jacuzzi with a beer in your hand.
- Most conferences try for a 80/20 mixture of serious stuff (sessions) and fun stuff. At SSOW they go for a 50/50 mix. That does not mean there is less serious stuff, just a lot less time to sleep. :)
I gave two presentations. The first one was a completely new one called Working with SQL Server in an agile development environment (though I think I will change that to Agile Data Practices if I give it again). Even though there where only a few attendees I still had a good time, since it was easier to get a good discussion going.
The other presentation was Understanding CLR Integration which I did for the fourth time. I think it went very well, with a lot of good interaction from the audience. I think it was the atmosphere at the conference that encouraged this, I know I saw it in other presentations as well. Two specific things where mentioned in the talk, which I promised to address here:
- Regarding user-defined aggregates (UDAggs) that can be created as CLR objects, we discussed the problem of the 8000 bytes limitation for MaxByteSize. As I said, this limitation really makes it impossible to use UDAggs for a lot of cases where they would otherwise be an option, for instance the often used examples of calculating a median or concatening strings. However, the really interesting bit is that I posted a feedback item regarding this to Microsoft Connect during the SQL Server 2005 beta testing period. What I said was that the maximum needs to be higher, possibly even indefinite. As the feedback item shows the response from Microsoft was that this was a reasonable request but since it was a non-trivial change it would not make it into SQL Server 2005 (RTM). Wednesday evening however this feedback item was closed and marked as fixed! Unfortunately it does not say how it was fixed or in which version (future service pack of SQL Server 2005, or Katmai the next version of SQL Server?) it is fixed. I am hoping that this gets clarified in the feedback item and also discussed it with Mark Souza from Microsoft who was there (with Lubor Kollar) as speakers and Microsoft representatives.
- The other thing was a question regarding the fact that not all system assemblies can be loaded in SQLCLR. The question was if the list of approved assemblies is available somewhere. I found this blog post by Bob Beauchemin to be a good answer.
Download the presentations (as PDFs):
- Working with SQL Server in an agile development environment (with demo code)
- Understanding CLR Integration
All in all I had a great time. If you are a SQL Server speaker I would definitely recommend putting in an abstract for a session next year.
