Category: Design

On self-documenting code

Take this piece of code:

public int Count(string text)
{
    Console.WriteLine("Counting...");
    // simulate some lengthy operation...
    Thread.Sleep(5000);
    return text.Length;
}

What’s wrong with it?

It’s not very obvious what the magic number 5000 means? Does it mean 5000 years? 5000 minutes? 5000 the time it takes to run around Main Market Square in Kraków?

Sure, you can hover over the invocation (if you’re in Visual Studio) and see the tooltip

selfdocumentingcode

and see that the number denotes milliseconds, but then you (as well as the junior programmer who will maintain the codebase) have to remember what a millisecond is, and what it means to wait 5000 milliseconds.

The problem is, that millisecond is not the most natural unit of time for humans, so I can assure you that the first thing the aforementioned junior programmer will do when he inherits the code will be “refactoring” it, to this:

public int Count(string text)
{
    Console.WriteLine("Counting...");
    // simulate some lengthy operation...
    Thread.Sleep(5000);// waits 5 seconds
    return text.Length;
}

What this means, is not that junior developer is not very bright – no. Quite the contrary – he would be doing the right thing, only the wrong way. He would be increasing the readability of the code by documenting it. However, he would not have to do that, if the code was self documenting.

So how do we fix that? For example, like this:

public int Count(string text)
{
    Console.WriteLine("Counting...");
    // simulate some lengthy operation...
    Thread.Sleep(TimeSpan.FromSeconds(5));
    return text.Length;
}

Unit tests – keep it simple (KISS)!

I have a tendency to overcomplicate things sometimes. Unit tests, are one such piece of code, that you want to keep as simple and clean as possible, so that other developers can easily find out how your class-or-method-under-test is supposed to work. There’s a principle for that that says it very strongly – “Keep it simple, stupid.”

Don’t make it flexible when it does not have to be (just … hard code it). For example, when I was working on IInterceptorSelector support for Castle DynamicProxy, I had to test proxies without target, where return value is set by an interceptor.

My first attempt at it was to create ReturnDefaultOfTInterceptor class that for any given return type, would instantiate it with parameterless constructor. This solution would provide what I needed, but it was unnecessarily complicated and made the test less readable. I didn’t need a helper class (that’s what the interceptor was in this test) that would handle just any return type of just any method. For the test I was calling one method, with one return type, and that’s all I needed from my helper interceptor.

Once I realize that I changed the test to something like this:

[Test]
public void SelectorWorksForInterfacesOfInterfaceProxyWithoutTarget()
{
    var options = new ProxyGenerationOptions
    {
        Selector = new TypeInterceptorSelector<ReturnFiveInterceptor>()
    };
    var proxy = generator.CreateInterfaceProxyWithoutTarget(
    typeof(ISimpleInterface),
        new[] { typeof(ISimpleInterfaceWithProperty) }, 
        options,
        new ReturnFiveInterceptor()) 
    as ISimpleInterfaceWithProperty;
    Assert.IsNotNull(proxy);
    var i = proxy.Age;
    Assert.AreEqual(5, i);
} 

The ReturnFiveInterceptor class name clearly sais what the class does. Also the assertion in the last line is more obvious now.

So, keep your tests simple and readable, don’t generalize where you don’t really need to, but know your limits, because when you cross the line you’re on the fragile tests territory.

Technorati Tags: , ,

Good comments, bad comments

As developers from our first years we are taught by our masters: “Comment your code you should, my young apprentice”. I even found this article, that outlines 13 rules, on how you should comment your code. I only have two rules for that:

  1. Don’t comment what your code is doing. If you find it necessary, it’s a code smell, and you should start thinking about refactoring it, so that it’s obvious.
  2. Do comment why your code does what it does.

Other than that, merry Christmas and happy new year everybody.

Technorati Tags:

Multilingual .NET applications. Enter .NET localization

Creating multilingual applications is a huge topic. There are whole books devoted to it, and if you’re serious about it, you should definitely read those, because what you see on surface, is only the tip of an iceberg.

If you only want to play with localization or need a quick reference, hopefully this post will help.

Fist thing is, .NET is really well thought of if it comes to localization, so if you know what you’re doing, it’s pretty painless to create application that will be easy to translate to other languages (localization is a LOT bigger topic than showing labels in different languages, but I’ll leave this topic out.)

Second thing is, localization mechanism in .NET is greatly based on conventions, and it’s what we’ll focus here.

First obvious rule is, that each string, picture, video… generally speaking localizable resource must not be hardcoded.

If you don’t hardcode resources where do you keep them? In (surprise) Resources file. Generally you can use .resx files, or plain .txt, though the latter are useful only if you only keep strings.

resourceFile

Visual Studio has pretty good support for editing resources in .resx files, and later I’ll show you another tool that can do it as well.

To access the resources programmatically you need ResourceManager class. To instantiate it you need to give it the part to resources within an assembly, and the assembly itself. If it’s a little bit unclear, here’s the example:

resourcePath

If the Visual Studio project is named LocalizableApp, and the .resx file we want to use is in folder Properties, and the file itself is named Resources.resx, the whole base name for the resources is “LocalizableApp.Properties.Resources”.

That’s where the compiled .resx file (.resources) will be located within the assembly. You can see it, if you open the compiled assembly with Reflector.

resourceLocation

So to instantiate the ResourceManager you’d write code similar to the following:

var manager = new ResourceManager("LocalizableApp.Properties.Resources", typeof(Program).Assembly);

Each resource is identified by it’s unique name string. For example in the picture below, we have two resources with names, “greeting” and “howAreYou”

resourceEditor

You use these names to get the values of the resources. The resource manager does its magic, to provide you with resources best matching the CultureInfo you provided. If you don’t provide any Culture, current thread’s CurrentUICulture is used. So if you write:

Console.WriteLine("{0} {1}", manager.GetString("greeting"), manager.GetString("howAreYou"));

The CultureInfo object held in CurrentUICulture property of currently executing thread will be used. The default value for this property is the same as language version of Windows OS the program is executing on, which is reasonable. If your user uses Polish Windows she will probably want to interact with Polish version of your app as well.

You may not rely on this default though, and either override the Thread’s property, or specify the culture explicitly when calling methods on ResourceManager, like so:

culture = CultureInfo.GetCultureInfo("pl-PL");
Console.WriteLine("{0} {1}", manager.GetString("greeting", culture), 
    manager.GetString("howAreYou", culture));

Of course you wouldn’t hardcode the culture the way I did in the example, because it would defeat the purpose of using culture in the first place.

OK, so how to add another language?

You have the .resx file with the default, fallback resources, right? So now all you need is either send the file to a localization company, sit back and enjoy life, waiting for them to do the hard job, or do it yourself. To go with the latter option, you may want to use a tool to edit resource files, called Resourcer, by Lutz Roeder (Reflector, people!).

resourceResourcer

You can easily edit any kind of resources in it (not only strings). When you’re done translating your resources, save the file as .resources file, using following pattern: {baseResourceName}.{culture}.resources. For example if you were to translate our example app, to German language as spoken in Germany, you’d save your edited file with the following name: LocalizableApp.Properties.Resources.de-de.resources

It is important to obey this pattern, as by convention, this is what ResourceManager expects. If you fail to obey it, ResourceManager will not be able to pick your translated resources and will fall back to the default.

Having translated and properly named .resource file we need to make a satellite assembly out of it. To do it, you need Assembly Linker (al.exe) tool that is part of .NET SDK.

al

There are multiple properties you can set with al, the minimal version to get valid satellite assembly is shown on above screenshot. One thing that’s important to note, is the name of resulting satellite assembly. Again, by convention it has to be {NameOfBaseAssemblyWithoutExtension}.resources.dll, so if our application assembly was named LocalizableApp.exe, satellite assembly must be called LocalizableApp.resources.dll

Notice that the name of the assembly is the same for every culture. So how do we deal with that. Obviously we can’t have two files with the same name in one folder. The way it is handled, is through subfolders. Each satellite assembly is held in a folder which is named after the culture of the satellite assembly.

resourceFolders

For example if our LocalizableApp.exe is held in a folder, let’s say Debug like on the above screenshot, the de-de satellite assembly would be Debug\de-de\LocalizableApp.resources.dll and for instance pl assembly would be in Debug\pl\LocalizableApp.resources.dll.

I hope this is all clear by now. The greatest thing is, to add new language you don’t even need the actual base assembly. All you need is its resources and their location within the assembly.

Technorati Tags: , ,

My $0.02 on internal sealed API vs public virtual discussion

Accidently this post hit the wave of discussion on the blogosphere regarding Microsoft’s approach of keeping very big chunks of APIs internal, sealed, or otherwise unusable by users, and backward compatibility.

To some extent I can agree with both sides, because as always, the truth is in the middle, and I believe we’re talking about the solution (keeping things non-public and non-extensible) instead of the actual problem (the way API is designed, that makes a lot of useless parts public, and useful parts non-visible).

One ridiculous example I saw is the IlGenerator class.

  • It’s public
  • Most of it’s methods are virtual

But

  • All of it’s constructors are internal

So it’s OK for me to use this class, but I can’t subclass it? Sure it reaches into the guts of the framework, dancing with the devil himself, by manipulating IL stream, but this all looks to me like a carrot on the stick.

From the Good News Department, my colleague Monika started a blog today. She’s a WPF geek, so if you’re into this stuff as well, you should keep an eye on her blog.

Technorati Tags: ,