BDD: Implementation og tilbageblik
Nedenfor er vist min første implementation af kode i EconomyDeluxe:
using System;
using Domain.Interfaces;
using System.Collections.Generic;
using System.Collections;public class GeneralLedger:IGeneralLedger
{private Dictionary
_accounts;
public GeneralLedger()
{_accounts = new Dictionary
(); }
public void AddAccount(ILedgerAccount account)
{if (account == null)
{throw new ArgumentNullException(”Null account supplied”);
}
if (!account.IsValid)
{throw new ArgumentException(”Invalid account”);
}
if (_accounts.ContainsKey(account.AccountId))
{throw new ArgumentOutOfRangeException(”AccountId is already present”);
}
_accounts.Add(account.AccountId,account);}
public void DeleteAccount(ILedgerAccount account)
{if (account == null)
{throw new ArgumentNullException(”Null account supplied”);
}
if (!_accounts.ContainsKey(account.AccountId))
{throw new ArgumentOutOfRangeException(”AccountId is not present”);
}
_accounts.Remove(account.AccountId);}
public IDictionary Accounts
{get{return _accounts;}
}
}
Man kan med rette sige, at mit første eventyr ud i BDD har været forholdsvis simpelt. Det er dog ikke en begrænsning for at kunne se styrken i paradigmet. Jeg har implementeret de første to User Stories i programmet - og brugeren har sagt god for det. Brugeren har noget at vise sin chef (okay, han bliver sikkert ikke voldsomt imponeret, men bare vent til den næste iteration…) - fix og færdig funktionalitet. Programmet kan det, vi har bedt det om at kunne. Det er en af de ting, jeg er mest begejstret for i BDD - ting opfører sig som man har specificeret. Og hvis de ikke gør, så vil en af den række specifikationstests afsløre det ved næste gennemkørsel af test-suiten.
Koden er stort set selv-dokumenterende. Indtil videre har jeg ikke behøvet skrive kommentarer til koden. Ikke at det er en hindring for at gøre det - jeg bør gøre det senere, men jeg har ikke tænkt mig at trætte dine øjne med det - kodeeksemplerne er lange nok i forvejen. Nu kan man vælge at tro mig eller lade være, men ovenstående kodestump tog mig under 5 minutter at skrive. Der er ikke et gram unødig kode. Der er ingen bloat. Der er lige nøjagtig nok kode til at brugeren er glad, hvilket gør mig glad (skizophreni er nu en underlig ting, at skulle forholde sig til).
Men nogen vil måske sige, at det er totalt overkill, at jeg har brugt over 4 gange så mange linjer på test/dokumentation/UL som på kodelinjer i implementationen. Jeg er ikke enig. Min påstand er, at den x5 faktor med antal linjer stadig er mindre end hvis jeg var startet med at implementere fra starten uden User Stories, fordi jeg så ville have skullet ændre ting midt vejs, slette unødig kode, som virkede som en god ide på det tidspunkt.
Og ikke mindst, jeg slipper for at dokumentere kode, som ville have været mere knudret, fordi jeg uanset mine gode intentioner ville være startet med at løse 8 forskellige funtionalitetskrav på en gang (”Når nu jeg alligevel er ved at lave properties… så kan jeg ligeså godt oprette de her tre andre, som jeg sikkert får brug for… ooh, og alle ved at man skal bruge en IsDirty…) og det ville have været starten på bloat. Hvis det ikke er et krav fra brugeren - så er det per definition bloat. Brugeren har talt - og han sagde at det vigtigste for ham var at han ville kunne oprette og slette finanskonti. Ville det så ikke være fjollet at begynde at lave et avanceret logging system? Ja, skåret ud i pap, men det er hele essensen i, hvorfor de fleste projekter ender på de evige bit-marker. Det er brugeren der betaler - og jo hurtigere han kan se, at han får det han har bedt om - jo mere villig er han til at betale.
Oh ja, og det bedste af det hele? Jeg er ikke det mindste i tvivl om, at min kode virker, fordi jeg har ikke skrevet noget kode, som ikke er testet. Jeg har rent faktisk en code-coverage på 100%!