Lita på dina objekt- Mjukvaruarkitektur del 1
Lita på dina objekt- Mjukvaruarkitektur del 1
Att kunna lita på sina objekt är en grundpelare för att kunna bygga robusta och pålitliga system. Spridda null-kontroller, tillståndsförändringar och felhanteringar bidrar alla till instabilitet och osäkerhet. Läs vidare för att se hur ett sånt enkelt medel som encapsulation förbättrar din kodbas.
Att kunna lita på ett objekt betyder att man aldrig behöver kolla om objektet är null, aldrig behöver tvivla på att dess värde är felaktigt – finns en instans av ett objekt så är det korrekt och säkert att använda. Här nedan går jag igenom ett par enkla medel för att uppnå detta – först ut är encapsulation.
Encapsulation
Alla system har någon form av extern beröringspunkt – det kan vara ett WebbAPI, en användare som matar in värden, eller en WCF-tjänst. Dessa beröringspunkter tar oftast in värden som IDn och uppdaterade egenskaper på entiteter. Dessa värden är ofta primitiver och strängar som sedan skickas ned i systemets lager för att hamna i en databas. När man skickar vidare dessa värden till metoder längre in i systemet får man automatiskt frågeställningar som “vad händer om värdet är si eller så” eller “vad händer om strängen är null eller tom”. Metoder längre ned ska inte behöva bry sig om sådant utan ska bara bry sig om HUR värdet ska användas.
En lösning på detta är att tidigt enkapsulera sitt värde i ett objekt. Med tidigt menar jag direkt vid den externa beröringspunkten. En enkel men användbar form av encapsulation är ett objekt som tar in en parameter i konstruktorn, validerar parametern och tilldelar den till objektets enda publika egenskap. Valideringen är viktig här, om värdet är ogiltigt (null till exempel) bör ett undantag kastas. På detta sätt säkerställer ni att ett objekt aldrig skapas om det inte är korrekt. Givetvis backar vi upp denna validering med enhetstester.
När en instans är skapad kan vi säkert skicka vidare objektet ned i systemet – och systemet kan lita på objektet.
Immutability
I brist på ett bra svenskt ord som har samma klang (oföränderlig fungerar kanske?) – immutability. Ett objekts tillstånd är låst efter dess instansiering. När ni låser ett objekts tillstånd fås ett antal trevliga effekter. Dels blir objektet trådsäkert eftersom det inte kan ändras och dels kan man lita på dess innehåll – ingen annan part har ändrat på dess värde. Dessa egenskaper är mycket värdefulla och gör systemet både robust och enkelt att resonera kring.
Validering
Jag har redan berört validering men det är värt att nämna igen. Inte allt för sällan skickas t.ex. personnummer genom system som strängar. Inte allt för sällan valideras personnumret på flera ställen eftersom varje del av systemet inte kan lita på att värdet faktiskt är validerad sedan tidigare.
Bygg in denna validering direkt i konstruktorn och verifiera detta med enhetstester så kan man lita på sitt personnummer till 100% i övriga delar av systemet. Om personnumret är ogiltigt bör ett undantag kastas eftersom man per definition inte skall kunna skapa personnummer som inte är personnummer.
Förväxla inte dina argument
En ypperligt trevlig effekt av encapsulation av värden i ett objekt är att det blir mycket svårare att förväxla sina argument till metoder. Nu får vi en typsäkerthet – dvs. kompilatorn säger ifrån om man försöker skicka in ett personnummer på telefonnumrets plats i argumentlistan.
Summering
Ovanstående punkter är lågt hängande frukter som har en överraskande god smak. Följer man dessa enkla principer kommer man få en kodbas som är att lita på. I en förvaltningssituation blir det också väldigt lätt att bygga ut och förändra koden då fokus kan läggas på kärnvärdet i den nya funktionen – inte på huruvida inparametrarna är korrekta. En sista mycket trevlig effekt är att null blir en utrotningshotad art – mycket trevligt!
Jag avslutar med ett exempel som väl summerar vad jag skrivit om: