Monthly Archives: June 2011

Criticality and Communication

My wife and I had a discussion last night as we walked home from a screening of the extended edition of Lord of the Rings: Fellowship of the Ring.

Being a nerd, engineer, computer scientist, programmer, coder, web developer, or any other such title that you can lump us into, is hard. The increasing complexity of technologies and languages mean that we have to constantly keep learning, otherwise our abilities will languish and fall behind.

As hard as that is, it can be even more difficult for nerds because of the way their brains are wired. The biggest difficulty for some is actually around interpersonal relationship skills. We nerds find others behavior to be strange and alien; We don’t always understand. We marvel at how easily it can come to some, but at the same time we find that behavior baffling, because we don’t think the same way. We see the world through monochrome tinted glasses; A world of boolean logic, in which something either is, or it isn’t. This polarizing conviction is the same thing that drives a lot of deep seated views, holy wars about technologies, which editor to use, whether to put the braces on the same line or a new line, etc. We’re also very critical of those things which are not tidied, tied off, cleaned up, made parallel, and understood.

When you confront someone with a different view from their own, and that view is firmly seated in their mind, something psychologically interesting happens. They  actually end up sticking to what they know more adamantly than before. This is known in the psychology community as the ‘backfire effect‘. My wife postulated that this might actually be the cause of many of the world’s big problems (religious wars, government stances on moral issues, etc).

Nerd psychology is a vast, complex topic. The personality of the ‘alpha geek’ is so pervasive in the industry of software engineering, that you can often times learn how to deal with anyone of the type just by observing one. The know-it-all arrogant attitudes are like a poison, a poison which threatens to turn our programmers world of creation into a cesspool of bickering. It’s easy to dismiss someone as not being as intelligent, but it’s a lot harder to discover where your intelligence has holes. The value of other perspectives in software engineering cannot be overstated, and is too often a blind spot for otherwise gifted developers.

Unit Testing Principles

Writing good unit tests is challenging. Over time I’ve accumulated a number of principles about what to do in unit tests, as well as what not to do. This is an incomplete list:

  • Test every possible code path. This means that for each ‘if’ statement, you’ll have at minimum 2 tests. Also known as code coverage.
  • Write your tests first. TDD is a hard mindset to get into, but well worth it.
  • If you have doubts about whether your code will do what you intend, you haven’t written enough tests.
  • Your tests should never make calls to external resources such as a database, filesystem, etc.
  • Every test should be self-sufficient and isolated. Your tests should not rely on other tests, or external factors. Be skeptical of setup/teardown code for a test harness class, as it can indicate shared state. (xUnit embraces this by not supplying that functionality.)
  • Don’t test outside your code. There is no need to write test cases for an assembly you are dependent on.

These are just some of the core principles for good testing, there are many more and I’d encourage you to look into them.

Const vs readonly

In C# when you want to have a named constant you have a choice between ‘const’ and ‘readonly’. For example:

public const string FooConst = "Bar";
public static readonly string FooReadonly = "Bar";

Which is appropriate?

Assembly Recompilation

You should only ever use ‘const’ on private fields. Using ‘const’ on a public field means that constant must be compiled into any consuming assembly. You might ask why having a constant compiled into consuming assemblies is a problem: The issue is that if you change that field, all consuming assemblies must be recompiled. Using ‘static readonly’ will not require consuming assemblies to be recompiled.

Flexibility/Mutability

Using ‘const’ is only possible with primitives, other value types, and strings, as its value is burned directly into the assembly. ‘Readonly’ on the other hand has no restrictions whatsoever, since it’s just a one time allocation of memory that has measures in place to prevent modification.

Also important to note is that ‘readonly’ only prevents the reference from being modified, not the actual memory being pointed to by the reference. To illustrate, the following is legal:

    public class Foo
    {
        public static readonly IList barReadonly = new List();

        public static void AppendString(string newString)
        {
            barReadonly.Add(newString);
        }
    }

Run time vs Compile time

A ‘const’ must be initialized immediately in code, and is initialized at compile time. A ‘readonly’ can be initialized at runtime, so long as it’s taken care of before the ctor exits.

Summary

In general, use ‘const’ when you know for certain that a value will never change, ever, or if the value is private. Otherwise, use ‘static readonly’.