Mini Musing #2

When talking about the Source Control “Git”, there’s so much jargon to throw around. Pull, Push, Fetch, Sync, Clone, Stage, Rebase, Squash, Branch, Merge, Commit, Tag…

I was talking to the Junior Developer about Git, and he comes out with this gem:

“When I think about Git, it reminds me of the game Bop It!”

“Fetch It”, “Pull It”, “Push It”

Commit Messages

Now that we have moved to Git, our Lead Developer seems to be making more of an effort to promote good “commit” messages. Over the last few months, we have joked about the quality of some of the commit messages in TFS, and how useless and frustrating they are.

“Fix bug 1756”
“Address code review comments”
“correct previous check-in”
“fix crash”

All of these don’t describe what has happened, or why the code has changed. With any code change, you always know it has happened to fix a problem, be it: a crash, performance issue, or refactoring to make the code easier to read.

There’s plenty of times when I’ve been investigating a bug, and you track it down to a particular file. Then you view the history of the changes to try and understand at what point the bug was introduced. When you are greeted with any of the examples stated above, then you have to look at each change and look at the linked Work Item (Bug Report). It’s great when you can just glance at the commit messages and can jump straight to the most likely culprit.

Say you are investigating a issue with Threading and you see:

“Minor refactoring of the DisplayInfo method”
“Change threading to use a threadpool”
“Add null check to prevent crash after clearing data”

You can then just jump straight to the change that clearly states there’s a change regarding threading.

I overheard the Lead Developer tell Derek to write a detailed commit method for his latest change and he says “seriously? I never write a detailed commit message; linking a Work Item is enough”.

I was face-palming. Surely, with a few months development experience, you will learn that good commit messages are very helpful. You could argue it only saves a few clicks and a few minutes here and there; but why make your job, or other people’s jobs harder?

Useless Git

As part of my employer’s technology refresh, we will now be using Git as our source control (alongside Azure DevOps), moving on from Team Foundation Server (TFS).

Although using Git requires a different way of thinking, it is still a type of source control, so the same steps of checking out code, making changes, and checking in still applies.

I get into work, click a few buttons to “Clone” the source (it took around an hour for that to complete though), then click a few more buttons to set up a branch. Since I had been making changes before the switch-over, I then copied my changes that I had been doing in TFS into my Git repository. After 2 hours, I had my code uploaded to the server and had a decent understanding of the process.

Today, Derek was doing the same process, and by the end of the day, he had finally sent his “Pull Request” (Code Review in TFS terms)…with the assistance of the Lead Developer. He then exclaims “that’s a fairly successful first attempt”, then goes home.

Sorry to disappoint you Derek, but this is a trivial process which took you 5.5 hours longer than me, and required assistance of the Lead Developer.

Mini Musing #1

In C#, when you create a Winforms form, you get a “.cs” file where you can write your own code, then a “.Designer.cs” file which is autogenerated. Every time you make a change using the Design View, it will regenerate the “.Designer.cs” file, so you should never manually change it.

    #region Windows Form Designer generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()

As you see in the example, it has a region which says “generated code“, then the next part is a comment that says “do not modify the contents“. So even if you don’t previously know it’s a generate file (as I described in the first paragraph); you sure do now.

Today, I got a code review where the InitalizeComponent method had been manually changed. Idiots.

Polymorphism

This blog entry probably requires some basic understanding of programming in an Object Oriented language.

A technique in Object Oriented programming is to take advantages of Base Classes or Interfaces to make code more reusable.

So you could define an Interface with a method on it, lets say IAnimate, and you could create a class, let’s say “Animator” which takes in some kind of object that can be animated. So the constructor would look something like this:

private IAnimate  animatedObject;

public Animator(IAnimate animatedObject)
{
_animatedObject = animatedObject;
}

Then let’s say this class also has a method that calls the method defined in the interface.

public void PlayAnimation()
{
animatedObject.Animate()
}

As long as your defined objects implement the IAnimate interface, you can pass them into the Animator class. The Animator class doesn’t need to know anything about what objects implement it. It doesn’t have any dependency on Cat, Dog, Fish etc. In the future, more animals can be added to the program, and the Animator never needs to change. Simple to understand for a Junior Programmer.

Colin came up with a class which completely rendered this concept pointless.

private Dog _dog;
private Cat _cat;
private Fish _fish;

public Animator(IAnimate animatedObject)
{
_dog = animatedObject as dog;

_cat = animatedObject as cat;

_fish = animatedObject as fish;
}

public void PlayCatAnimation()
{
_cat.Animate()
}

public void PlayDogAnimation()
{
_dog.Animate()
}

public void PlayFishAnimation()
{
_fish.Animate()
}

So with this design, we are still passing in an interface, but there is some bizarre casting going on in the constructor, and we save the result to the appropriate variable. We also have a method for each implementation of IAnimate, so there’s a separate method for Cats, Dog, Fish, even though they do exactly the same thing. Whatever class actually uses Animator has to know what type of animal it is for, because creating an Animator for a fish, then calling PlayDogAnimation() will crash. In the future, when new animals are added, Animator will not work without extra code changes. You would need a new variable and new method for each type of animal.

Any advantage that Polymorphism brings has been completely eradicated with this design. All that has happened is that there’s extra complexity and crashes. It shows a complete misunderstanding of such a fundamental technique to Object Oriented Programming.