Monday, April 20, 2015

An overview of things I find important in coding

A while ago, I had to introduce a developer with little experience in modern .NET development to a project I am leading. I gave the usual talks about the architecture, picked some classes to clarify, explained patterns we use, etc.

But I also wrote down some basic principles that are important in the project. When I read them again, I realized they're some core principles I find very important when coding. I know there are many principles out there to adhere to, but these are the ones I stress the most to colleagues and team-members.

Communication, communication, communication

 

Something I learned from Kent Beck's excellent Implementation Patterns (also available at Bol.com): when you're writing code, you're communicating. You're communicating with other coders, now and in the future, but also with yourself.

This is something to always keep in mind. I cannot stress this enough. Always be thinking if your code clearly communicates what it is trying to achieve. Most other principles more or less follow from this one.

Single Responsibility Principle

 

While I have definitely written classes that violate this rule, it is important to work towards having a class being responsible for only one thing. If a new responsibility is introduced, split it out into a separate class. Possibly, you will need a third class to coordinate between the two class.

This sounds like extra work and it is (especially if there are unit tests involved!), which is what often holds people back. But the extra work you do now will be saved later when your application doesn't exist out of a few big classes where all overview is lost. You will more easily be able to look at a class and understand what's going on. And it will be easier to change or refactor. The class provides better and clearer communication about what its purpose is.

Dependency Injection

 

I've worked on projects that use Dependency Injection and on projects that don't. The projects that do have been more elegant and have made it easier to plug in different or new implementations of dependencies in classes.

Dependency Injection is, in my experience, something that is hard to explain to novices, but once you get it, you see it as a very elegant approach for complex applications.

Small classes

 

Keep your classes small. The Single Responsibility Principle should make this easier to achieve. What is small? Some blogger once pointed towards the fact that this wasn't always clear to new developers. He/she (can't remember who it was) proposed to use the arbitrarily chosen value of 300 lines as a maximum.

I find this generally works well. If a class is 300 lines or more, it's no longer readable. Just under 300 is of course also hard to read, but 200 is still more or less comprehensible. Still not ideal of course. But it provides a fairly good guideline to use for your classes.

On a side note: one class per file. Files are cheap and allow you to see the structure of an application by looking at the Solution Exporer (if using Visual Studio) or the directory. Also, when using a version control system, you can ask the history of a file to see the history of a class. You win nothing by putting multiple classes in the same file, even if they're small classes.

Method names, variables, properties, classes, etc are important

 

Communication again! Take a moment to think about the name of that variable and make it clear what it is.

And don't use abbreviations, it starts with using 'repo' instead of 'repository' and ends with using 'ddlPrefCustClass' instead of 'dropDownListPreferredCustomerClass'. You might have guessed this of course, but when a file is full of these abbreviations, it makes it orders of magnitude harder to read.

Code is written once, but read multiple times. Don't be lazy.

Small commits

 

If you're using a version control system (please don't tell me you're not!), work in small commits. This allows you to see your thinking/working process later, but it also avoids having to iterate over many classes after having implemented something wrong and wanting to roll back part of what you've changed while keeping other pieces.

Continuous Refactoring

 

When you see something in the code that's not quite right or can be improved, fix it. Maybe commit your changes first (small commits!) but definitely fix it. Code written now can be as beautiful as you imagined it, but a few days/weeks/months/years down the line, you might see it differently. It might not be as clear as it was back then. Now is your chance to fix it.

Code must constantly be maintained. It's never 100% perfect. It can collect dust and lose its shine. When you encounter this, polish up the code, even if only a little bit. It keeps the project alive and maintainable.

This is closely related to the Boy Scouts Rule, where you leave the place you're visiting cleaner than it was when you arrived.

Test-driven development

 

To me, this isn't the same as having tests. Test-driven development means you write your tests first. This is very important. It makes you think about what you're trying to achieve and how the public API of your method/class should look like to communicate (!) best. It also makes you order your thoughts about what you need and how you will implement it, instead of diving in without thinking.

After writing the test, write the minimum of code to make it pass. Then do the red-green-refactor cycle. First make the test fail (I have had cases where the test passes even though there is no implementation, especially when refactoring). Then fix it. And, often forgotten, have an extra look at the code and see if you can refactor it. Often, you can.

If you write your code first, and your tests last, it happens that you're testing what you wrote, not what the method or class should be doing. Also, you can end up with more code than necessary, have certain parts not under test, less clear code/API, etc.

I realize there are cases where TDD is not possible or hard. Refactoring and proof-of-concepts come to mind. But be honest, you're not refactoring or writing POCs 100% of the time, are you?

Conclusion 

 

I believe that keeping these things in mind will lead to a more readable and maintainable codebase. Both for yourself as for others coming after you.

A former colleague once said: "Writing code is like a visit to the bathroom. Always think about the people visiting after you." Spot on.

Wednesday, April 8, 2015

Easily finding if a date range contains another date range

Here's a quick tip. If you need to find out if a given date range is covered by another date range, this code does the trick.

Let's say you have an Event class with a Begin and End property and a SearchFilter with a Begin and End property. If you search for events between April 8 and April 12, you would want the following events to be included:
  • April 7 to April 9
  • April 11 to April 14
  • April 9 to April 10
But you don't want the following events:
  • April 6 to April 7
  • April 13 to April 14
This is actually fairly easy, but requires you to compare the begin with the end and the end with the begin.

Confused? Here's some code:

public class SearchFilter
{
    public DateTime Begin { get; set; }
    public DateTime End { get; set; }

    public bool Includes(Event evt)
    {
        return evt.End >= Begin && evt.Begin <= End;
    }
}

That's all there is to it. This image clarifies it a little more:
The blue block is the date range of the search filter. The green blocks will return true, as they are covered by the filter. The red blocks fall outside of the boundaries of the filter, so they will return false.

Thursday, March 19, 2015

A generic JsonConverter for Dictionaries and JSON.NET

JSON.NET is a great tool and it already handles Dictionaries well, unless your keys are classes (as opposed to structs). Say you have the following class you want to serialize:
public class DataPoints
{
    public IDictionary<DataPointKey, int> Values { get; set; }
}
And the DataPointKey class:
public class DataPointKey
{
    public int Length { get; set; }
    public int Height { get; set; }
}
I'm just making stuff up here, don't mind the actual contents of the class. The important thing is that the key of our Dictionary is a class.

When you let JSON.NET serialize this, you will get the following:
{"Values":{"JsonDictionary.DataPointKey":200}}
Notice how the key is just the class name. This will not deserialize nicely.

In the past, I would create a custom JsonConverter, but this meant repeating code over and over when new keys were introduced. Inheriting from a base converter was my first solution, but I've finally found a converter that can handle any Type.

The result is a little more verbose, but serializes and deserializes nicely:
{"Values":[{"Key":{"Length":10,"Height":20},"Value":200}]}}
The entire code is a little too long to post here, but I've made a Gist you can check out.

Sunday, March 8, 2015

International Women's Day: women in tech

Contrary to what you might think today, the worldwide community of technology professionals (data entry, programming, etc etc) used to be predominantly female. In fact, our industry was built upon the hard work of women (there are more and longer articles on this subject, just google around).

And yet now, I haven't had a lot of female colleagues. When I'm at a tech show or conference, there are hardly any women. There is a slowly growing feeling that this has to change, along with all the sexist practices (booth babes, etc) and incidents that have happened in the past and are still happening today.

I'm confident any industry only has to gain with a more diverse composition. And because it's International Women's Day*, I thought I'd list some great female techies I follow and look up to.

Hopefully, this can
  • convince older female tech-professionals they're not alone
  • convince younger female tech-enthusiasts that a career in the tech industry is possible and worthwhile
  • convince the macho male techies out there to change their attitude
Here goes:
  • Leslie Cottenj√©: owner of Pureplexity, a startup from Bruges, my home town; I've seen her do a great session on Metro apps and the work her agency delivers is fabulous.
  • Iris Classon: possibly the wackiest and most energetic programmer out there; she went from no-programmer to great-programmer in a time I envy.
  • Kelly Sommers: more often than not, I have no idea what she's tweeting about because her work is so technically challenging (think big data and crazy algorithmic stuff).
  • Sheree Atcheson: founder of WomenWhoCode UK, actively encouraging more women to become coders.
  • Mary Jo Foley: not a coder, but a highly regarded tech journalist, mainly covering Microsoft. She's also on the (recommended) Windows Weekly podcast and a beer-enthusiast, which, as a Belgian and beer-lover myself, I can only encourage.
  • Jenn Lukas: a great front-end developer and co-host of the Ladies In Tech podcast.
  • Val Head: the other co-host of the Ladies In Tech podcast, a CSS lover and organizer of Web Design Day.
  • Kathleen Dollard: MVP, Pluralsight and Wintellect author, featured on DotNetRocks.
  • Suz Hinton: programmer, IOT enthusiast, coined the fabulous term 'Nerdiverse' (as far as I know)
This is just a short list of the great women in our small tech-world. Follow the links and you will definitely find even more women who are active and successful in the tech industry.

Also, if you have a daughter and want to get her started, check out GoldieBlox :)

And for the book-lover, O'Reilly recently published Women in Data

Finally, to my female colleagues and friends: happy International Women's Day!

Update: I was pointed to a great article by Uncle Bob on the subject. A must-read.

*If you think (like I've heard some people say) that International Women's Day is no longer necessary, you're not following the news. If you think it's no longer necessary in our Western world, you don't know the tech industry or haven't been paying attention (just two links I found while googling "sexism in tech industry".

Friday, March 6, 2015

Comparing a local file with a workspace file with C# and TFS

The situation is simple:
  • we need to send messages to another system
  • the developers of the other system need documentation on the layout of these messages
  • this is a company-specific protocol (no JSON or anything standard, because we're talking to old Fortran machines here)
  • naturally, the documentation is made in Word files
Taking an example from a session I saw at ngEurope, I decided we might be better off auto-generating this documentation. Keeping Word files in sync with the evolving code is a tedious, manual process, not to mention that the Word files are never in sync 10 years down the road.

And as the code is the single point of truth, I started on automating the process. I hate repeating manual things. It's boring, allows for manual error (I remember updating a production SQL database instead of the beta database!), and needs to be taught to newcomers time and again.

So:


After having written code to generate the documentation (too specific to put here), I needed a way of having the build automatically add the new file to the pending changes, or if nothing had changed, undo the checkout (sadly, I'm on TFS; git would not have this problem).

So this is how you can compare a local file with the server version of the file:
private bool HasFileChanged(string file, TfsTeamProjectCollection server, Workspace workspace)
{
    string diff;

    var versionControlServer = server.GetService<VersionControlServer>();

    var serverPath = workspace.GetServerItemForLocalItem(file);
    var serverVersion = new DiffItemVersionedFile(versionControlServer, serverPath, VersionSpec.Latest);
    var localVersion = new DiffItemLocalFile(file, Encoding.UTF8.CodePage, DateTime.Now, false);

    using (var stream = new MemoryStream())
    using (var writer = new StreamWriter(stream))
    {
        var diffOptions = new DiffOptions
        {
            Flags = DiffOptionFlags.EnablePreambleHandling,
            OutputType = DiffOutputType.Unified,
            TargetEncoding = Encoding.UTF8,
            SourceEncoding = Encoding.UTF8,
            StreamWriter = writer
        };

        Difference.DiffFiles(versionControlServer, serverVersion, localVersion, diffOptions, serverPath, true);
        writer.Flush();

        diff = Encoding.UTF8.GetString(stream.ToArray());
    }

    return diff != "";
}
The server and workspace variables can be made like this:
var workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(file);
var server = new TfsTeamProjectCollection(workspaceInfo.ServerUri);
var workspace = workspaceInfo.GetWorkspace(server);

Friday, February 6, 2015

Avoiding the information madness

A while ago, a colleague asked how I tracked all the information that's coming in: Twitter, RSS, Facebook, blogs, podcasts,... It's easy to drown in all the information if you want. I won't pretend I have the ultimate strategy, but here's what I do.

Facebook

I'm not on Facebook for a variety of reasons (mainly this), but I don't miss it. So that's one information-source less to deal with.

Twitter

This has been my usage of Twitter:
  • Ignore the hype
  • Check out the hype, follow a handful of people
  • Love it and check it everyday picking up where I left of the day before
  • Start following more people; create lists
  • Whoa, too much! Just check it now and then to pick up anything interesting that was posted that last hour or so. Plus, use it when I write a blog post (self-promotion yay!) 
So I gave up any hope of keeping up with Twitter. Twitter is like entering a newspaper-shop. There's all sorts of magazines, newspapers, books, comics, etc. And you can't go there everyday and read it all. Just go there when you feel like it and read some stuff, check out any favorites, then move on.

RSS

Since Google Reader was discontinued, I briefly used The Old Reader, but after a while, I switched to Feedly. I can't really remember why I made the switch. Possibly because the Old Reader was experiencing load problems at the time (because thousands of developers were moving from Google Reader to the Old Reader). I hear it no longer has these problems, but in the mean time, I'm happy at Feedly.

I use NextGen Reader on my devices to connect to my Feedly. Great app.

Podcasts 

After following blogs for a while you collect a large amount of blogs to follow and read. Lately, I notice I don't take as much time to read them as I used to. Also, reading blogs is subject to ups and downs based on how busy work is, how busy home is, how I feel, etc.

Podcasts are my new information source. While you can't follow as many podcasts as you do blogs, the good ones provide a wide range of information. My commute is about 45 minutes which is perfect to follow several podcasts throughout the week.

Here's my selection, in no particular order:
There are definitely episodes that I skip, but not all too often. Here, again, you have to be able to skip content without feeling bad or getting the feeling you'll be missing life-or-death-crucial stuff.

Must read but have no time 

A final tip is to have a way of setting things aside for later. I use Pocket, but there's also Instapaper, and possibly others. I find it's easier to add stuff than it is to actually read any of it later, but now and then I do take the time to catch up.

Conclusion

It is hard/impossible to keep up with everything in our fastly-evolving world. And that is exactly why you shouldn't try. Just have a steady stream of information via the channels you are most comfortable with. You might miss out on the most minute details, but anything remotely important will be repeated by so many sources, you can't miss out.

Thursday, January 29, 2015

Wrapping an old-school callback-javascript method in a promise

When you have an older javascript library that supports asynchronous calls via callbacks, you might want to wrap them in a promise instead. Particularly if you're using Angular. For my own reference, this is how to do it. I'm using Angular's $q, but I suspect it should be more or less the same with Q.

Let's assume this is the method with the callbacks:

function goAsync(input, success, error) {
    try {
        // do something here
        success(result);
    } catch {
        error();
    }
}

Wrapping this in a promise is quite easy:

promiseObject.go = function(input) {
    var deferred = $q.defer();
    oldSchoolObject.goAsync(
        input,
        function(result) {
            deferred.resolve(result); 
            $rootScope.$apply();
        },
        function(e) {
            deferred.reject(e); 
            $rootScope.$apply();
        }

    return deferred.promise;
}

Notice how I call $rootScope.$apply after resolving or rejecting the deferred. This is so Angular starts its digest-cycle and the UI is updated.

Now you can use the promise:

promiseObject.go(input)
    .then(function() {})
    .catch(function() {});

You can see a live example of this in one of my GitHub repositories.