Sunday, November 11, 2007

Refactoring for Statistics

Code Squirrel
 I realized today, during a training session on SSIS, that I'm sort of a code squirrel. Whatever language I'm looking at the time (SQL, VB, Java, C#), I'm struck by a strong desire to start coding in that language.

Statistic
 Ok, let's wrap up getting statistics into the database. I've decided to (for now) keep the Canonical object, but I will replace hardcoded values with values loaded from a database. I want to break this down into steps, after each of which, the tests can be run. These steps should be as small as possible.
 In general, I want to replace the array of names (where the index defines the ID) with a dictionary object.

1. Add a Dictionary object, update Debug Print to display Dictionary object (generalized)
2. Update AddStatistic to write to the dictionary object as well.
3. Update Read function (FindStatisticByName) to look in dictionary object instead.
4. Update Read function (FindStatisticByIndex) to look in dictionary object instead.
5. Replace Read Property (AllStatistics) with reference to dictionary object.
6. Remove array from AddStatistic, etc.
7. Delete the array.

8. Load Statistics from the Database.

Add Dictionary
 Hmm... all tests pass, but I'm expecting that the debugPrint test would fail. Aha! There is no debug print test for this canonical statistics object. I'll create one. Ok, it fails. Time to add this snapshot to the database, and re-run. Excellent. Now I have a test to fail (:

Update AddStatistic
 Partially done, but this reveals another test that I'm missing - testAddSameStatisticsTwiceHasNoEffect. Interestingly, though, this is a private function (and, I think should be), so I can't test it. Ok, I'll update the function anyway, shrug, and move on. Done. No new failures (NNF).

Update FindStatisticByName
 Ok, reduced this function from 20 lines to 10. Tested, NNF. Good.

Update FindStatisticByIndex
 This is even easier. 12 lines to 6. Tested, NNF.

Missing step
 Also updated the destructor.

Update AllStatistics Property
 This is a bit tricky, as the array object and dictionary object are not interchangable. I could create an array from the dictionary and return that, but instead, I think I'll expose the dictionary, modify the calling code to use the dictionary instead and, when all the references are switched, remove the reference to the array.
 Failures. Confusion. Time for a little traditional debugging. Odd, an extra level of indirection solved the problem, but I don't see why. For now, it works, moving on.

Remove Array
 I'll start with an easy-to-revert test by making the property private. Done, NNF. Ok, now to obliterate the references one by one. Ah, this is a little tricky, as the index defined the key earlier. A little work to accept the index as a parameter instead. Ok, that works.

Delete Array
 Some additional simplification of DebugPrint (down two 5 verbose lines), and I finally delete the array. Okay, now I'm ready to change to a database driven approach, but that will have to wait for next session. Time for some Phantom Brave.