Sunday, April 21, 2013

Durandal + scrollspy

Recently, I played with the Hot Towel MVC template and tried to integrate Bootstrap's scrollspy. This was very difficult for me as my main topic is rather C# and WPF than JavaScript and Html. But after a struggle here and there, I found a solution. Not perfect (any improvements are welcome), but it's sufficient for me.

The problem is that Sammy.js, which Durandal uses for routing, does the routing via hashes (#), which apparently are also used for anchor-navigation. In order to prevent Sammy.js to incorrectly interpret the anchor-links, I added an invisible route for them to the viewmodel of the current page and route it there manually. Hard to describe, see the code!

 //shell.js:
router.mapNav('alpha', 'viewmodels/alpha', 'Alpha');
router.mapRoute('beta', 'viewmodels/alpha', 'Alpha', false);
router.mapRoute('gamma', 'viewmodels/alpha', 'Alpha', false);

In shell.js, in the activate-method, we register the normal route ('alpha'), and for each anchor-link within the alpha-page, another route that maps to the same page ('beta' and 'gamma'). Now, when you click on an anchor on page 'alpha', the activate-method of the corresponding viewmodel will be called with the anchor-value as parameter (see below).

 //alpha.html:

Nothing special for the html-part. The anchor-links are just normal relative anchor-links and the classes are mainly from bootstrap for the scrollspy- and affix-plugin.

 //alpha.js:
define(['durandal/plugins/router'], function (router) {
  var vm = {
    activate: activate,
    viewAttached: viewAttached,
    loaded: false,
    items: [
      { name: "Beta", link: "beta" },
      { name: "Gamma", link: "gamma" },
    ]
  };

  return vm;

  function activate(routeParameters) {
    if (routeParameters.routeInfo.hash != "#/alpha") {
      $(document.body).animate({
        'scrollTop': $(routeParameters.routeInfo.hash.replace("/", "")).offset().top
      }, 100);

      return false;
    }

    return true;
  }

  function viewAttached() {
    if (!vm.loaded) {
      vm.loaded = true;
      $('.bs-docs-sidebar').height($(".bs-docs-sidenav").height());
      $('.bs-docs-sidenav').affix({
        offset: $('#nav').position()
      });
      $('.bs-docs-sidebar').scrollspy();
      $('[data-spy="scroll"]').each(function() {
        var $spy = $(this).scrollspy('refresh');
      });
    }
  }

The activate-function is called whenever a route to this viewmodel is activated. When the normal alpha-route is activated, it is called with "#/alpha" as hash and nothing happens. When an anchor-route is activated, it is called with "#/beta" for example and we scroll to this anchor with jQuery.
The viewAttached-function is called when the databinding has finished. Clicking an anchor-link calls this method not for the first time and nothing happens. The important work is done on the first call: the height of the navigation-div is fitted to its content, the affix-parameter is set and the scrollspy is activated (twice, because I possibly do something wrong here *g*).

 //app.css:
.affix {
  position: fixed;
}
 // index.cshtml:
< body data-spy="scroll" data-target=".bs-docs-sidebar">

Don't forget the scrollspy data-attributes for the body-tag!

That's it :)

Sunday, November 14, 2010

Second sprint experiences of the Coding Dojo Helper

The motto of the second sprint was "Visual Studio Integration". On Microsofts website about VS-extensions, there are a lot of resources about extending the IDE. Unfortunately, after navigating around a bit, you quickly land on the boring msdn library pages. As I haven't found any nice tutorials on the web either, I had to find it out by myself: after downloading the SDK, there are new templates in the new project window under the Extensibility-folder. One of them is named "WPF Toolbox Control" and that sounded nice to me and so I took it ;)

Visual Studio Integration
Outline of a WPF Toolbox Control project
When you compile the project, you get a simple, empty dockable toolbox window inside of Visual Studio, like the properties-window but without the properties :)
The main classes of the project are the CodingDojoHelperVSExtension*.*-files, which specify the embedding of the extension into Visual Studio and MyToolWindow.cs, which is your entry-point in modifying the toolbox.
As I'm using Prism, my constructor (which is the complete code for MyToolWindow btw) looks like this:
[Guid(AGloballyUniqueIdentifier)]
public class MyToolWindow : ToolWindowPane
{
    public MyToolWindow() :
        base(null)
    {
        this.Caption = Resources.ToolWindowTitle;
        this.BitmapResourceID = 301;
        this.BitmapIndex = 1;
 
        var bootstrapper = new CodingDojoHelper.Bootstrapper();
        bootstrapper.Run();
 
        var shell = bootstrapper.Shell;
        shell.Background = new SolidColorBrush(Colors.Black);
 
        base.Content = shell;
    }
}
In my solution, I now have three projects:
  • CodingDojoHelper, which has all the logic and UI in it.
  • CodingDojoHelperDesktop, which references CodingDojoHelper and just provides the main window.
  • CodingDojoHelperVsExtension, which references CodingDojoHelper and just provides the IDE-integration.

I just need minor tweaks to adapt it to the 2 scenarios (like shell.Background = new SolidColorBrush(Colors.Black); instead of an transparent background for the desktop-version). This is really nice and I haven't thought that the integration would be so easy. However, I had two problems to solve:

Digest view with the new amCharts

  1. Every VS-extension must be compiled with a strong key. This means, every depending library also must have a strong key. It leads to the point, that I even need the strong key of Rhino Mocks, because I'm using the [assembly: InternalsVisibleTo]-attribute to be able to mock internal classes for unit-testing. Fortunately, Rhino Mocks provides a key callable via Rhino.Mocks.RhinoMocks.StrongName.
  2. I had to switch from WPF Toolkit to amCharts for this reason: the WPF Toolkit is not a published product and therefore, it hasn't got a strong name :( However, I like amCharts more by now :) I don't need to do much designing so that it looks good ^^
New features
Start-screen
What else is new in this sprint?
  • Start-screen: I've made a start-screen where you can select the target-duration of the TDD-cycles. When the time is up, you'll hear a nasty sound bite like "You weak pathetic fool" from the original Mortal Kombat game! So beware and keep your tests small and do make baby-steps to receive a saying like "Well done" from Shao Khan himself!
  • Beautified: You also have the possibility to set the total duration of the dojo and the number of combatants, that is developers. But these two items are just to show off yet, because they will gain meaning in the next sprint. I downloaded gif-animations of the fighters from an internet-resource and used a special class to make them move inside WPF - looks cool 8-) The other cool thing is a storyboard using an ElasticEase that makes the two buttons for modifying the times (which is indeed a styled scrollbar) swing into their new place. At first, I looked in Blend for the easing functions for WPF in vain. But then, I opened a Silverlight-project, build the storyboard there and copied the XAML into my WPF-project. Feels awkward, but works.
  • Config-screen
  • Config-Screen: This screen is also new to the Coding Dojo Helper and it was easily integrated with the help of Prism. Unfortunately, I haven't looked into Prism V4 and the new navigation possibilities - but this is another user story for me in the coming sprint(s).
  • Styling: I've done the same (styling with a Silverlight-project and copying the result into a WPF-project) with a Checkbox. That was needed, because the WPF-Checkbox is precompiled and therefore not decomposable into atomic WPF elements like Ellipse etc.
  • Gif-Editing: I edited my first gif-image inside of Gimp. The finish him-writing wasn't part of the image. So I opened the gif in Gimp, added 6 frames to it with the text and saved it back. It's as simple as that!
  • Adorner: It is now possible to select the keys used to switch a developer and to end the session. I grab the AdornmentLayer, make it 25% transparent and prompt the user to push the new key for it. Luckily, I had to make the same Adorner-job at work last month. So this was a no-brainer ^^
The Coding Dojo Helper is now fully functional and we use it at work in our weekly coding dojo sessions. When I finished my third sprint, it should be ready for release :D

Saturday, October 30, 2010

Training big refactorings with code katas

Recently, we had to refactor some methods out of a class into a new class. In the past, I already made some big refactorings saved by unit tests. Retrospectively, I must admit that my unit tests back then weren't unit tests but mainly integration tests: although I stubbed away the serial communication, my tests used always all layers of the program. So, instead of mocking C when testing D-->C (uses), I mocked A in D-->C-->B-->A. That means, if you want to refactor B in this chain to B'-->B'', you have to adjust all tests of C and D respectively. This is of course cumbersome.
Thank god, I almost always mock the next layer now, so that refactoring the tests is manageable. I even succeeded to refactor the tests step by step in a TDD-manner having mostly only 1 red test. To be able to do that, the Bank OCR-kata has helped me a lot. In this kata, you can do two class-refactor-steps in the first user story. I would like to present the second one in respect to clearly refactor the tests also (it helps a lot if you're familiar with this kata, so feel free to dive into it or even do a test-run for your own before reading further on).
Code so far:
public class BankAccountParser
{
  private readonly IBankAccountSplitter _bankAccountSplitter;

  public BankAccountParser(IBankAccountSplitter bankAccountSplitter)
  {
    if (bankAccountSplitter == null)
      throw new ArgumentNullException("bankAccountSplitter");

    _bankAccountSplitter = bankAccountSplitter;
  }

  public string Parse(string bankAccount)
  {
    if (string.IsNullOrEmpty(bankAccount))
      throw new ArgumentNullException("bankAccount");

    var bankAccountNumber = new StringBuilder();

    foreach (var digit in _bankAccountSplitter.Split(bankAccount))
    {
      if (digit == " _ | ||_|")
      {
        bankAccountNumber.Append("0");
      }
      else
      {
        bankAccountNumber.Append("1");
      }
    }

    return bankAccountNumber.ToString();
  }
}
Tests so far:
[TestFixture]
public class BankAccountParserTests
{
  private BankAccountParser _target;
  private IBankAccountSplitter _bankAccountSplitter;

  [SetUp]
  public void Setup()
  {
    _bankAccountSplitter = MockRepository.GenerateStub<IBankAccountSplitter>();
    _target = new BankAccountParser(_bankAccountSplitter);
  }

  [Test]
  public void Ctor_ObjectIsNotNull()
  {
    Assert.IsNotNull(new BankAccountParser(_bankAccountSplitter,
MockRepository.GenerateStub<IDigitParser>()));
  }

  [Test]
  public void Ctor_BankAccountSplitterIsNull_ThrowArgumentNullException()
  {
    Assert.Throws<ArgumentNullException>(() => new BankAccountParser(null));
  }

  [Test]
  public void Parse_Null_ThrowsArgumentNullException()
  {
    Assert.Throws<ArgumentNullException>(() => _target.Parse(null));
  }

  [Test]
  public void Parse_Zeros()
  {
    var zeros = " _  _  _  _  _  _  _  _  _ \n" +
                "| || || || || || || || || |\n" +
                "|_||_||_||_||_||_||_||_||_|\n" +
                "                           \n";

    _bankAccountSplitter.Stub(x => x.Split(zeros)).Return(new List<String>
    {
      " _ | ||_|",
      " _ | ||_|",
      " _ | ||_|",
      " _ | ||_|",
      " _ | ||_|",
      " _ | ||_|",
      " _ | ||_|",
      " _ | ||_|",
      " _ | ||_|"
    });

    var actual = _target.Parse(zeros);

    Assert.That(actual, Is.EqualTo("000000000"));
  }

  [Test]
  public void Parse_AOneAndZeros()
  {
    var oneAndZeros = "    _  _  _  _  _  _  _  _ \n" +
                      "  || || || || || || || || |\n" +
                      "  ||_||_||_||_||_||_||_||_|\n" +
                      "                           \n";

    _bankAccountSplitter.Stub(x => x.Split(oneAndZeros)).Return(new List<String>
    {
      "     |  |",
      " _ | ||_|",
      " _ | ||_|",
      " _ | ||_|",
      " _ | ||_|",
      " _ | ||_|",
      " _ | ||_|",
      " _ | ||_|",
      " _ | ||_|"
    });

    var actual = _target.Parse(oneAndZeros);

    Assert.That(actual, Is.EqualTo("100000000"));
  }
}
Now I would like to introduce a DigitParser-class which should parse one digit and return a 1-string-representation of it. Therefore, I introduce the interface for it:
public interface IDigitParser
{
  string Parse(string bankAccountDigit);
}
Next, I need to inject it into the target. To do that, I take the easiest test and rewrite it using the new interface:
[Test]
public void Ctor_ObjectIsNotNull()
{
  Assert.IsNotNull(new BankAccountParser(_bankAccountSplitter,
                                         MockRepository.GenerateStub<IDigitParser>()));
}
To make it green, just complete the constructor:
public BankAccountParser(IBankAccountSplitter bankAccountSplitter, IDigitParser digitParser)
{
  if (bankAccountSplitter == null)
    throw new ArgumentNullException("bankAccountSplitter");

  _bankAccountSplitter = bankAccountSplitter;
}
This makes all other tests red because they do not compile anymore. So, alter the setup-method
[SetUp]
public void Setup()
{
  _bankAccountSplitter = MockRepository.GenerateStub<IBankAccountSplitter>();
  _digitParser = MockRepository.GenerateStub<IDigitParser>();

  _target = new BankAccountParser(_bankAccountSplitter, _digitParser);
}
and one test:
[Test]
public void Ctor_BankAccountSplitterIsNull_ThrowArgumentNullException()
{
  Assert.Throws<ArgumentNullException>(() =>
    new BankAccountParser(null, MockRepository.GenerateStub<IDigitParser>()));
}
We're green again and ready for a next test: Assert that when passing in a null-DigitParser, an ArgumentNullException will be thrown.
[Test]
public void Ctor_DigitParserIsNull_ThrowArgumentNullException()
{
  Assert.Throws<ArgumentNullException>(() =>
    new BankAccountParser(_bankAccountSplitter, null));
}
This test is red and becomes green with following code:
public BankAccountParser(IBankAccountSplitter bankAccountSplitter, IDigitParser digitParser)
{
  if (bankAccountSplitter == null)
    throw new ArgumentNullException("bankAccountSplitter");

  if (digitParser == null)
    throw new ArgumentNullException("digitParser");

  _bankAccountSplitter = bankAccountSplitter;
  _digitParser = digitParser;
}
Now comes an interesting step, because we insert an hint into one test how to refactor the sut:
[Test]
public void Parse_Zeros()
{
  var zeros = " _  _  _  _  _  _  _  _  _ \n" +
              "| || || || || || || || || |\n" +
              "|_||_||_||_||_||_||_||_||_|\n" +
              "                           \n";

  _bankAccountSplitter.Stub(x => x.Split(zeros)).Return(new List<string>
  {
    " _ | ||_|",
    " _ | ||_|",
    " _ | ||_|",
    " _ | ||_|",
    " _ | ||_|",
    " _ | ||_|",
    " _ | ||_|",
    " _ | ||_|",
    " _ | ||_|",
  });
  _digitParser.Stub(x => x.Parse(" _ | ||_|")).Return("0");

  var actual = _target.Parse(zeros);

  Assert.That(actual, Is.EqualTo("000000000"));
}
All tests are still green, so we're ready to refactor:
public string Parse(string bankAccount)
{
  if (string.IsNullOrEmpty(bankAccount))
    throw new ArgumentNullException("bankAccount");

  var bankAccountNumber = new StringBuilder();

  foreach (var digit in _bankAccountSplitter.Split(bankAccount))
  {
    if (!string.IsNullOrEmpty(_digitParser.Parse(digit)))
    {
      bankAccountNumber.Append(_digitParser.Parse(digit));
    }
    else
    {
      if (digit == " _ | ||_|")
      {
        bankAccountNumber.Append("0");
      }
      else
      {
        bankAccountNumber.Append("1");
      }
    }
  }

  return bankAccountNumber.ToString();
}
Great, but this can be rewritten easier:
public string Parse(string bankAccount)
{
  if (string.IsNullOrEmpty(bankAccount))
    throw new ArgumentNullException("bankAccount");

  var bankAccountNumber = new StringBuilder();

  foreach (var digit in _bankAccountSplitter.Split(bankAccount))
  {
    bankAccountNumber.Append(string.IsNullOrEmpty(_digitParser.Parse(digit)) ?
      "1" :
      _digitParser.Parse(digit));
  }

  return bankAccountNumber.ToString();
}
But now, the last test is red. We haven't stubbed the DigitParser there yet. To do this, I move the stubbing into the setup-method and also add the canned answer needed for the last test:
[SetUp]
public void Setup()
{
  _bankAccountSplitter = MockRepository.GenerateStub<IBankAccountSplitter>();

  _digitParser = MockRepository.GenerateStub<IDigitParser>();
  _digitParser.Stub(x => x.Parse(" _ | ||_|")).Return("0");
  _digitParser.Stub(x => x.Parse("     |  |")).Return("1");

  _target = new BankAccountParser(_bankAccountSplitter, _digitParser);
}
Prepared like this, we tweak the production code a last time ending with
public string Parse(string bankAccount)
{
  if (string.IsNullOrEmpty(bankAccount))
    throw new ArgumentNullException("bankAccount");

  var bankAccountNumber = new StringBuilder();

  foreach (var digit in _bankAccountSplitter.Split(bankAccount))
  {
    bankAccountNumber.Append( _digitParser.Parse(digit));
  }

  return bankAccountNumber.ToString();
}
But this is not the end for the tests. Actually, we're just testing if the BankAccountSplitter and the DigitParser are working together correctly. So, instead of the last two tests, we should write:
[Test]
public void Parse_SplittedInto2Digits_ConcatenateDigits()
{
  _bankAccountSplitter.Stub(x => x.Split(null)).
    IgnoreArguments().
    Return(new List<string>
    {
      "foo",
      "bar"
    });

  _digitParser.Stub(x => x.Parse("foo")).Return("a");
  _digitParser.Stub(x => x.Parse("bar")).Return("b");

  var actual = _target.Parse("nonrelevant");

  Assert.That(actual, Is.EqualTo("ab"));
}
This points us to some more tests, I had forgotten initially like what happens when the DigitParser returns null or throws an error? What if the BankAccountSplitter has this behavior?

This scales pretty well to "real life" code and as said before, the training with this kata has helped me recognize this pattern during my work and the usefulness of it.

Thursday, October 7, 2010

Coding dojo helper - Mortal Kombat Edition

A colleague of mine told us that really good developers could do a red-green-refactor-circle in about 90 seconds. This sounds quite fast, but I thought that maybe one day we could achieve that... To help getting a feeling for the time spend doing such a circle, I wrote a tool. This tool should take the time of each developer doing a round and calculate the average time of a complete timebox used for a kata, for instance.

Learned new tools :)

As a kata originally comes from martial arts, the tool got a touch of the famous video game Mortal Kombat ^^ For development, I used Blend, Gimp and Audacity to do the design and learned some new tricks. For example, one can draw an ellipse with Blend and select Object --> Path to convert it into an animation path. This path can be used in a storyboard to make a button go round another control for example:
The second thing I've learned is to capture keystrokes even if the window isn't active. This article of Stephen Toub has shown me how to do that. So, if the user presses the Scroll-Button, the stopwatch starts. If he has finished his work, he presses the Scroll-Button again and the next developer begins to code. At the end of the timebox, one presses the Pause-Button and the screen changes to show the average TDD-time and a chart listing all times:
Neat, he? This is also the first time I used a DCVS.


The first attempt was to use Git, GitHub and TortoiseGIT as mediator. But as I'm developing this on a company-laptop during my ride home, there were some difficulties accessing GitHub and I abandoned this quite fast (I do think there are ways to circumvent this, but I hadn't got the nerves to look for them any further). So I tried Mercurial, Kiln and TortoiseHg and it worked like a charm. If you want, you can fetch the sourcecode at codingdojo.kilnhg.com and have a try for yourself if you can master the red-green-refactor-mantra in under 90 seconds. On our first try, we set the alarm to a moderate 3-min-timeout, but did a 4:30 min in average *ouch*. Next time, we'll use a 4-min-timeout and are keen to beat that :)

Sunday, September 26, 2010

Coding dojos

At work, we do weekly coding dojos since 2 1/2 months now - and it's great!
Every thursday at 11am we meet in front of a computer and start a 1h-timeboxed session. This session consists of 3 parts: discuss kata, code, retrospective.

Discuss kata
First, we decide which kata to start with. If we haven't finished the kata from the week before, we throw away the results and start again from scratch including finding a common interpretation of the requirements (e.g. does an account number consist of 3 or 4 lines). Throwing away the work you have already done is not painful at all. Actually, it is necessary to improve yourself. Seeing direct improvements (e.g. completing a part of the kata which was never touched the week before) is priceless!

This part should be as long as necessary but as short as possible. At the moment, we need more than 10 minutes before writing our first test. I think we can cut that into halves in the coming weeks.

Code
At the moment, we work on the Bank OCR-kata and haven't finished the first user story yet. Before this kata, we successfully finished the katas Prime Factors and Roman Numerals *proud*. We do the katas (as well as our actual real-code-pair-programming) in a flow-Randori system:
The first person to be on the keyboard creates the test-project and writes the first test. After that, we play a round of musical chairs and the next developer solves the test. When it's green, he has the chance to refactor the code using baby-steps. Having finished the refactoring, all he has to do now is to write the next test and initiate the next round of musical chairs (which doesn't necessarily needs music to play in the background).
I think doing this kind of system is perfect when you're 4-6 people. Are there more than that, you would probably more likely do the prepari system. But being 10+ developers, I would rather split the group into two halves than having one big group where not everyone can participate.

Retrospective
About 5 minutes before the deadline, we begin the retrospective and try to find out what was good or what can be better next time. Right now, we're far away from a fast TDD-circle: approximately 5 minutes lasts a red-green-refactor-mantra, which surely can be lowered to 2 minutes.

In my opinion, every company writing software should have a regular coding dojo in the calendar. It helps enormously to spread a common coding style. Everyone learns from everyone, be it new keyboard-shortcuts (- is my newest) or amazing tools like R# or Visual Studio Power Tools.
With coding dojos, it is easy to integrate new team members and guide them in learning TDD. All in all, I highly recommend that!

Sunday, June 13, 2010

Prism is witchery

For my newest project, I wanted to use Prism to guide us writing a decoupled WPF-application. I started investigating it and was quickly amazed about the module-approach. In our former WinForms-project, we didn't used a framework to guide us building a nice architecture, but developed our own clsForms-class (at that time even with hungarian notation *awkward*) and used even IPC to communicate across process-boundaries.

I began writing the framework for the new project with heavy guidance of Prism (RegionManager, EventAggregator, DelegateCommands and CommandBehaviors). In the end, we had some modules building a master-detail view with database-access. This was the time when other coworkers started to complain that the architecture is way too complex for such a small application as it is today. We started to discuss how to simplify it and at the end we had a draw in our opinions: some people wanted to keep everything (me included *g*) and some wanted to strip it down to remove Prism, to abolish dependency injection and the IoC container Unity. Our boss had to decide it and spoke to us: "thou shalt remove Prism but keep DI for a better TDD").

The top-3 reasons why Prism is evil for us* are:
(*) i.e. not for me

3) Using the app.config for setting up the modules is error-prone and not type-safe.
I told them that we could do it in code also but somehow I got not heared :/

2) Debugging is too hard.
When you get an exception in a view which will be inserted into a region, you got this Prism-Exception telling you that there was a problem resolving this module for that region. I learned here that you cannot expect everyone to look at inner-exceptions (admittedly mostly at level >5)...

1) Top reason why Prism is evil: it is too intransparent how the regions get filled (witchery *hooo*).
What can I say? For sure, you have to look at the good documentation at their homepage to get the hang of it. Else it's witchery, yes.

So we burned it and removed it from our solution with 10+ modules and about 10,000 loc. We needed 5 hours to remove the lightweight Prism-sections completely and substitute it with our own RegionManager-approach (which is basically the same) and with our own DelegateCommand-approach (wich is basically the same) and without the help for commanding of Prism (we now use code-behind to execute the commands). Ah yes, and we copied the EventAggregator out of the Prism-sourcecode and use it now, because our approach would be basically the same...

Everyone feels better now that the evil is being distroyed.

What was the problem? We're using a whole bunch of new technologies and paradigms in this project (WPF is new to us, as Entity framework, WCF, Prism, TestDrivenDevelopment and dependency injection). This means a lot to learn and sooner or later, your retentiveness is exhausted. This meant to sacrifice a pawn, in this case it was Prism.

Tuesday, December 8, 2009

Another book, another kata

This unit testing book by Andrew Hunt and David Thomas is better than the last one, but I made the mistake? to start reading The art of unit testing in parallel (when I've finished that book, a review will be posted as well). So, nothing bad about the pragmatic book, but nothing good either. It covers NUnit (already with "That") and only strives mock-frameworks. There are a plenty of tips how to write good unit tests, among them mnemonics like "Right BICEP", "A TRIP" and "CORRECT". There is even a Pragmatic unit testing summary in checkbox-format. As if I'll go through all the rules after writing a test *lol*
All in all, a good book - but I'm looking forward to "the art".

Staying by Dave Thomas, I've done his sixth kata "anagrams" a few times and I always learned a new shortcut, trick or whatever. I rarely use the mouse anymore and I've downloaded ReSharper (because we're using NUnit instead of MSTest now) and took benefit from the smooth integration of the refactorings. DevXpress had to go unfortunately.

Here, I've found a nice introductory-video in the principles of coding katas, if you're interested.

Here is a video about the randori-variation.

Uncle Bob takes this approach a step further and declares coding kata as an art. See him performing the prime factor kata to music! here.

Thursday, November 26, 2009

Code katas

I just finished my first code kata :) I did FizzBuzz, a very easy one just to get started. I wrote the last code-bit for the last test to past in a quarter of an hour. Therefore, I continued with "stage 2" of the kata.
I wanted to make it easy to extend and got lost half the way :( There was a point where I refactored too much without unit testing. This was bad because the bigger the steps the more likely it is you have to go a step backwards.
Luckily, I got my act together and accomplished my plan. The rest was fine and all tests passed.
On a second try, my goal is to don't use the debugger anymore (I needed it twice) and take baby steps.

Wednesday, November 18, 2009

PDC 2009

It's PDC again! Yesterday, I watched the opening-keynote. They spoke about the cloud and the new Visual Studio and how they can interact. A database store, codename Dallas, was shown which tries to unite data from all over the world - surely nice to play around with.
About half the time, when talking about the cloud, they showed this list:

1970s: Mainframe
1980s: Client-Server
1990s: Web
2000s: SOA
2010+: Cloud

We're just working on to get to the 90s, great...

One new feature of VS2010 is intelliTrace, which is a history of the program running via the debugger. I hope we switch to VS2010 soon, because that sounds interesting.

Last year, a lot of sessions were recorded and put online. I hope they'll do it this year alike. Nevertheless, don't forget to watch the second keynote today (17:30 CET) at the website with Scott Guthrie.

--------------------------------------------------------------------

The second keynote was great! Silverlight 4 beta available now! With trusted mode!! File system access!!! *download*

Monday, November 16, 2009

Test-Driving

The plan is to do a 2-week-bootcamp right before christmas to learn / get experience with test driven development (TDD). I already tried to practice it and I must say that it's hard. Though writing tests before you implement feels natural (I somewhere read "developing without testing is like driving a car without fastening your seatbelt"), it is so much contradictory to what I'm used to develop (test last development; if tests at all). Because of that I looked for some help in books.

From the first one I only read two chapters online: Test Driven: Practical TDD and Acceptance TDD for Java Developers by Lasse Koskela. You can find the chapters here. As I'm a .NET-developer, a Java-book is not worth purchasing, I think. However, I mention this book because these two chapters are really good. The first one is about beginning TDD. This is the usual stuff about red, green, refactor by example. The second chapter is the one that enlightend me. It talks about how to integrate the testing in the development-process (eXtreme Programming, that is) with acceptance TDD. The following picture is from Lasse's book and opened my eyes. Never before was the test-integration so clear to me. This is the only way how a developer will write good tests: write an acceptance test and make it green via several unit test driven development-cycles.
The other chapters sound interesting - maybe I'll find this book in a library.

Test-Driven Development in Microsoft .NET by James W. Newkirk and Alexei A. Vorontsov is the other book I recently read. I got this book from my good friend Uwe (*winkeWinke*). This book has a foreword by Kent Beck - so this has to be good, I thought. But actually: it isn't :( The first three chapters are OK - the standard-introduction section. Then, the book tries to write a whole example-application with TDD. I must admit, this is courageous - but it fails. I don't think that someone will work through all this code in order to understand how to test a database, a web-service, a web-client, etc. At the end, all tests are more or less the same. I think it is more helpful to learn TDD with your own little project than with this book. By the way, the technology used (ADO.NET instead of Entitiy Framework, ASP.NET Web Service instead of WCF, ASP.NET instead of Silverlight!?) is old...

Tuesday, November 3, 2009

2 agile books and one IOException

I just finished 2 books about agile development: User Stories Applied by Mike Cohn and Scrum and XP from the trenches by Henrik Kniberg.



Mike Cohn covers all about user stories. As we're just beginning Scrum with a new project, we will be doing a story writing workshop with some business people. So, User Stories Applied is probably the right book for that.
After not much blabla and good tips, page 49 describes what to do in such a workshop. He suggests to find the top epic stories and break each down. Page 182pp shows the place of a workshop within the path to begin programming:

1) Perform user role modeling
2) Trawl for high-level user stories <-- Start workshop
3) Prioritize stories
4) Refine high- and medium-priority stories
5) Organize stories into groups
6) Create a paper prototype <-- great if we'll reach that in the workshop
7) Refine the prototype
8) Start programming

I think the hardest thing is to gather the top 25 epics. This will be difficult with people discussing each and every detail don't focusing at the higher level. But as this will be the first workshop, we can still learn if things go astray :)

Here's a passage I liked (about 'why user stories'):
"Humans used to have such a marvelous oral tradition; myths and history were passed orally from one generation to the next. Until an Athenian ruler started writing down Homer's The Iliad so that it would not be forgotten, stories like Homer's were told, not read. Our memories must have been a lot better back then and must have started to fade sometime in the 1970s because by then we could no longer remember even short statements like "The system shall prompt the user for a login name and password." So, we started writing them down." (cf. IEEE 830)

So, good book, nice to read and great for looking up user-story-things.



The second book I finished is Scrum and XP from the trenches which is a war story on doing scrum. Lots of hands-ons and lessons-learned stuff. Some parts are interesting like how to handle multiple scrum teams but the most part I heard or read already. If you're new to scrum and agile methods, this is amusing to read (like how to negotiate with the PO). If not, you can scroll over it (as I read it as a free eBook).

And now for the IOException. I made some debug-sessions lately and now and then I came across an IOException just reading "the file exists" when calling GetTempFileName. I loaded old, already released code and even with this *cough* high-quality-code the exception will be thrown. Luckily I found this blog-post dealing with the same problem. Just delete some temp-files (approx. 100,000) and everything works fine now :)

Thursday, October 22, 2009

Sketchflow

We're started a project and are now in gather-requirements-phase. I sketched some UI-views for my module and Alex said: great - can you scan them in so we can discuss them with Uwe from Hamburg?
I remembered that I've heard something about Sketchflow which is build into Expression Blend. Sketchflow is a rapid prototyping software which lets you design new UI-sketches very fast. So I surfed to Sketchflow overview and thought "well, I'll give it a try". So I downloaded Expression Blend 3 and a Starterkit with some neat videos. While installing, I watched the first one and was impressed what you can do with that piece of software: build your UI using predefined toolsets, add navigation to your sketched application and even gather feedback from various persons via a Sketchflow-player.
After 3 and a half hours of work, I sketched all paper-sketches into Sketchflow and showed it to Alex and Reinhard. Gosh, they were impressed. Here are two screenshots:

This will be the first screen after a import has finished. They suggested to delete the buttons and integrate the navigation into the colored labels.

This shows how easy it is to create a rich screen in just a few minutes. If you wish, you can even use real data imported into Expression Blend! And best of all: it makes a lot of fun ^^

Monday, October 12, 2009

Pair Programming

Puh, just finished a pair programming-session with Artem. This was hard work!
We started at about 14:00 and wanted to add some unittests for a class Artem wrote. I already reviewed his code, so I knew it quite good. By the way, one result of the review was "where are the unittests?" - so I maneuvered myself in this position. Anyway, good quality-code needs some sacrifices *heroic*
I took the keyboard and Artem the mouse... No, just kidding. He was sitting beside me keeping an eye on my cursor. So we began with the first function and let Visual Studio build a test-stub and an accessor (yes, I love that!) for us. We discussed what to test for this method and I began to write code for it - easy. Not long afterwards, we found the first inconsistency which wasn't visible in the review and in the productive code either. Fixed it and continued. This went on and on, one unittest after the other. We discussed the relevant parts of the code and enhanced a few places.
But as time goes by, I noticed how unconcentrated I was and that I made more and more typos. What a luck that we almost had all unittests we longed for. So we created the rest and finished that session. It was 16:00 and I was exhausted like never before when writing some code.
I must say, that this was hard, but it was worth for it. You can't get such a tight feedback-loop when doing reviews and you can't produce code just by discussing it in a normal meeting. So, pair programming is great but exhausting!

Friday, September 4, 2009

CodeRush Xpress

Some time ago, I tried ReSharper, but wasn't totally convinced to spend > 100 Euro - so I forgot about it. As I'm doing more and more refactorings (you know, I'm on my way...), I really felt that there could be tools to help me. I read some forums and found CodeRush Xpress. Just have a look at the introductory video here and you want to work immediately with it.
I discovered that tool the day before I went on a 1-week-no-pc-holiday-trip. As I came back, I was eager to try it and it held all my demands.
I'm using + + <+ / -> (Selection increase / decrease), the camel-case navigation and on a variable (show appearance). And of course I'm using + <ö> (german layout) to call the refactorings. It's nice how you get a visual feedback for an upcoming refactoring:

There's so much so discover for me. There's also a kind-of mod-community, because the API is open (DXCore) to extend. Great tool!

Wednesday, August 5, 2009

How to build a collection of Interfaces

Here’s the problem: we have some files and some devices which operate with signals. As a signal is one of our main objects, we want to return a collection of signals when opening a file or beginning a communication with a device:

But of course, we want to handle each signal the same, so a signal from an EDF-file should be from the same class as a signal from a device. We could define a signal-class in the Main-library like this:

But this constructs a circular reference. We could create a converter for each special signal and build a collection in the main-library of all signals:

Ouch – ugly. For every signal-type we need one converter. What happens when DeviceSignal changes? Hopefully, we update the corresponding DeviceSignalConverter... Here’s my solution:

We implement all interfaces a signal could be loaded / imported from in the main-signal-class and use generics to simulate a factory. A EDF-dll could have:


public interface ISignal {
int SamplesPerRecord { get; set; }
}

public class SignalReader where T : ISignal, new() {
public override ICollection GetSignals() {
List signals = new List();
var signal = new T();
signal.SamplesPerRecord = 3;
signals.Add(signal);
return signals;
}
}

The signal in the main-library implements that interface:


public class Signal : ISignal {
public int SamplesPerRecord { get; set; }
}

We can now call the SignalReader and it returns us a collection of signals we can use:


public ICollection GetSignals() {
SignalReader reader = new SignalReader();
return reader.GetSignals();
}

We can implement further signal-readers just by implementing the necessary interfaces into the main-signal-class. In fact, for each reader we created from Signal inherited classes implementing the interface the reader defines. With that construct, we can work without circular references and get a collection of objects we can work with.

Wednesday, July 8, 2009

Benefit for unit tests

From today on I’m absolutely convinced that unit tests are great.

The last three days I refactored my current project a lot – in fact I added 10 classes, deleted 6 and changed 25. If I would have done that in the past without unit tests, I a) wouldn’t have done that and b) if I really would have done that, it would have probably taken me 2 weeks to realize that my uncontrolled changes aren’t working and I wouldn’t get it to work in a reasonable amount of time.

But with my 250 unit tests, I checked every refactoring-step if my code still does what it has to do. And with that, I was absolutely sure about my changes. So, thank you, unit tests!

Monday, July 6, 2009

Clean Code


I just read the german edition of Clean Code from Robert C. Martin. The introduction made me love this book immediately by a simple drawing. There are two things I’ll take along from this book:

1) For each function f let f.LinesCount < 20

2) Comments are evil

These two rules need some clarifications of course. In fact, the demand to keep functions below 20 lines is a result of another rule: Don’t mess with abstraction-levels. If you see a function with more than 20 lines, this should be a good indication for a mix of different levels of abstraction.

The second rule points in the opposite direction of what I’ve learned at university: one tutor said to me that there should be more lines of comment than lines of code, so that another person could easily understand what you wanted to say. Today with C# and Java, this isn’t true anymore. The code itself became the comment. No more cyptic function-calls or Hungarian notation but intuitive named functions and variables telling what they’re doing.

Although I’m still feeling awkward without any function-header-comment, I slowly try to reduce unnecessary comments like this:

‘ iterate through all alarms
For Each a In m_colAlarms

And transform it into this

For Each alarm In _alarms

The difference is not big but the sum of all changes generates a nice picture.

So, the first dozen chapters are truly inspirational. After that, the book takes a look on bigger examples how to refactor whole classes. This is done step-by-step and after some steps, it’s getting boring. My advice: just read the first 12 chapters and start coding!

Wednesday, June 10, 2009

What a wonderful world

Recently I read a lot about the M-V-VM pattern and I wanted to try it out. So I started small with a WPF-application implementing a listview showing some events related to sleep medicine. I’ve created a simple model with a collection of various data. This model is the data-provider for a ViewModel which is databind to this view:



So far, so good; worked pretty easy. I then read something about the graphical ability of WPF, which should be very bad in displaying a lot of graphical objects. Again, I wrote a sleep-medical-application, but this time showing some random biosignals with events:



The problem here was the very long signal build of thousands of Polyline-segments. And indeed, this brought WPF to its knees. You can’t show some signals with the pure use of WPF-technology. I instead used GDI+ inside of a Canvas-element for the signal and the VirtualCanvas-technique for the events (read here about it). With that I managed to preserve databinding on the modifiable objects (the events): you can move them around and change their duration by dragging their border.

In a second step, I combined the model of the ListView with that of the biosignals and injected it into its ViewModel. Of course, every ViewModel is being unittested – what a wonderful world:


Thursday, June 4, 2009

C#-For and VB.NET-For

Yesterday I wondered why on earth my simple VB.NET-For-loop produced an error:

Dim collection As New List(Of Integer)
collection.Add(1)
collection.Add(2)
collection.Add(3)
collection.Add(4)
collection.Add(5)

For i As Integer = 0 To collection.Count - 1
Console.WriteLine(collection(i))

If collection(i) = 2 Then
collection.RemoveAt(i)
End If
Next

I’m coming from a Java / C#-background, so I tried the same loop in C#:

var collection = new List<int>();
collection.Add(1);
collection.Add(2);
collection.Add(3);
collection.Add(4);
collection.Add(5);

for (int i = 0; i < collection.Count; i++) {
Console.WriteLine(collection[i]);

if (collection[i] == 2) {
collection.RemoveAt(i);
}
}

Et voilá, the result is what I wanted. So I made my discovery of the day: C#-For isn’t VB.NET-For.

In the cold light of day and using the debugger, it seems obvious that the VB.NET-For doesn’t check the condition on every iteration. It just duplicates the loop as often as it is stated in the For-statement.

The C#-construct is smarter as it checks in every iteration if the condition is true. But if it’s true that this is the difference between the two Fors, then the C#-loop must be slower. So, let’s check it out:

Dim start = DateTime.Now

For i As Integer = 0 To 1000000000
' nothing
Next

Console.WriteLine(Now.Subtract(start).ToString())

Vs.

var start = DateTime.Now;

for (int i = 0; i < 1000000000; i++) {
// nothing
}

Console.WriteLine(DateTime.Now.Subtract(start).ToString());

And indeed, the VB.NET-For-loop wins on my system with 3.734s to 4.687s!

Sunday, May 17, 2009

Thread-Threat

At work, I'm trying to get a software-feature faster by introducing multithreading. We import data from a device and convert it into our format. This is done sequentially at the moment, first importing, then converting. First tests have shown that we can get a benefit of about 30% if we do that in parallel. So I developed a wonderful producer-consumer-queue with a producer-thread and a consumer-thread which gets its data from the producer-thread. So far, so good: all unit-tests with that queue ran successfully.

However, as soon as I plugged that code into the import-conversion-piece to make it multithreaded, I got System.Runtime.InteropServices.COMExceptions with HRESULTs of -2147467259 (RPC_E_SERVERCALL_RETRYLATER, Unspecified error) or -2147417856 (RPC_E_SYS_CALL_FAILED, System call failed) - (here is a list with automation errors). These errors occured randomly on different parts of the code. But all code-parts had in common that they're calling a VB6-COM-object (well, it's a COMException - what should I expect...).

Some googling brought me similarities with Office-automation (see here and here for example). My picture about that problem became clearer and clearer and I sketched that diagram to understand it:


Thread A and B are accessing the same COM-object. This access is provided via a RCW (runtime callable wrapper). There is only one RCW for all accesses to that COM-object (read the great article series "Beyond (COM) Add Reference: Has Anyone Seen the Bridge?" of Sam Gentile for a deeper dive into COM-interop). This means multithreading and COM-interop is no fun.

What about protecting the access to that COM-interop with a lock? I designed a little construct so that I won't forget to protect any calls to that COM-interop:


The wrapper for the COM-interop, ThreadSafeComInterop, offers the COM-interop via a Lock-class. Each time you want to access the COM-object, you acquire the lock. With that, a Monitor enters the lock and exits it not until the lock is disposed. It's neat with the using-construct:

Using lock = _interop.Lock
' do something with lock.ComInterop
End Using

See that sequence-diagram for further information:


The provider creates the ThreadSafeComInterop by passing the COM-interop to the constructor. The recipient can call the Lock via the using-construct and access the COM-interop via lock.ComInterop. By creating the ThreadSafeComInteropLock, a Monitor.Enter is established on a static lock-object. When finished using the COM-object, the Lock is being disposed and Monitor.Exit is being called to allow other components to access the COM-object.

This sounds great and tests are showing that the exception-rate is degreasing from 10 tries - 9 exceptions to 10 tries - 1 exception. But unfortunately, this exception is one exception too much. Reading "Lessons Learned Automating Excel from .NET" finally convinced me to write the needed parts of the COM-component in .NET.