Tankar kring mockning och dependency injection

författad av Kauppi 2009-02-11 19:05

Det som jag tycker kännetecknar en bra arkitektur är att den är så ren och enkel som möjligt. En sak som jag tycker har en tendens att smutsa ned och komplicera arkitekturen är en överanvändning av Dependency Injection (DI). Ett populärt syfte med att använda DI är att förbättra och snabba upp testbarheten av systemet genom tex mockning. Om DI till stor del baseras på detta syfte finns det en risk för suboptimering, dvs man optimerar testbarheten av systemet på bekostnad av renhet och enkelhet i den tekniska arkitekturen.

Den största nackdelen med en omfattande klassisk implementering av DI är att antalet interface i arkitekturen ökar. Detta leder i sin tur till att arkitekturen blir mer svårnavigerad för utvecklaren. Detta eftersom interfacen försvårar för utvecklaren att snabbt finna naturliga flöden i systemet. Om utvecklaren tex stegar igenom koden och stöter på ett interface så finns det olika stöd (tex "Find all references" i Visual Studio) för att finna den aktuella implementering av interface:t. Detta arbetssätt kan jag acceptera om DI implementeras av andra syften än för att förbättra testbarhet samt om DI implementeras med rimlig omfattning.
 
Jag gillar heller inte att arkitekturen smutsas ned med kod bara för att förbättra testbarhet av systemet. Testbarhet har egentligen inget med systemet i sig att göra och därför bör den påverka arkitekturen så lite som möjligt.
 
Kan man förbättra testbarhet av systemet utan att arkitekturen tar större skada av det? Det finns lite olika lösningar för detta. Det bästa vore om olika integrationslösningar (som tex Nhibernate, Entity Framework, Enterprise Library, Windows Communication Foundation) erbjöd ett standardiserat stöd för mockning av objekt och andra resultat. Detta vore den bästa lösningen men troligtvis kommer det inte att inträffa inom den närmaste framtiden.
 
En annan lösningsvariant är att skapa en enkel återanvändbar wrapper runt en specifik integrationslösning. En sådan wrapper har i huvudsak två funktioner:
1) Den första funktionen är att autogenerera mock-objektet eller resultatet utifrån olika metoder som anropar den faktiska integrationslösningen. Detta innebär i sin tur att utvecklaren slipper att manuellt skapa mock-objekt. Möjligheten för att skapa manuella mock-objekt bör dock finnas. Det borde även finnas en möjlighet att skapa flera olika mock-objekt för en och samma metod där identifieraren för mock-objektet är inparametrarna till integrationsmetoden.
2) Den andra funktionen med wrappern är att utifrån en enkel configurationsinställning avgöra när den faktiska integrationslösningen eller den mockade varianten ska användas.
 
En sådan här wrapper kommer med stor sannolikhet hålla arkitektur ren och enkel samtidigt som den förbättrar testbarheten av systemet. Wrappern bör inte vara svår att skapa. Själv har jag inte skapat en sådan wrapper fullt ut men jag har gjort några lyckade experiment. Jag började med att pröva spara de olika autogenererade mock-objekten i textfiler men jag kom ganska snabbt fram till att det bästa var att spara mock-objekten och resultaten i en databas. Det blir en liten overhead att använda sig av en mock-databas. Denna overhead är dock relativt marginell och skulle man vilja så kan man bygga in cachning av mock-objekten.

Den wrapper jag gjorde var väldigt simpel men när jag gjorde den så fick jag en mängd nya idéer på hur den skulle kunna förbättras. En sak som jag saknade var tex ett lätt sätt att administrera de olika mock-objekten som skapats. En annan sak som vore bra att bygga in är en möjlighet att upptäcka inaktuella och icke-valida mock-objekt. En integrationswrapper öppnar även möjligheter för tracing, loggning m.m.
 
För att avrunda detta blogginlägg så kan man säga att en förbättrad testbarhet av systemet är förenligt med en ren och enkel teknisk arkitektur. Lösningen för att uppnå denna förening är inte genom en omfattande implementering av Dependency Injection utan genom att skapa wrappers runt olika integrationslösningar.
 
Hör gärna av dig om du testar att skapa en integrationswrapper. Det är alltid intressant att höra andras erfarenheter!

PS. Kanske bör jag tillägga att jag också är skeptisk till en överanvändning av DI för att uppnå flexibilitet i arkitekturen. Allt behöver inte vara flexibelt bara för att det går. I vissa fall behövs det medan i andra fall är det överdesign. Denna överdesign är en slöseri med kundens pengar och något som inte främjar enkelhet och renhet i den tekniska arkitekturen. Flexibilitet låter bra men den har sina konsekvenser som måste beaktas.

Versionshantering av databasen samt andra databastips

författad av Kauppi 2008-10-30 18:36

Det finns lite olika sätt att versionshantera en databas. Nyligen fann jag ett verktyg i "Visual Studio Team System for Database Professionals" som hanterar detta på ett rätt bra sätt.  Genom detta verktyg kan man versionshantera databasstrukturen via Team Foundation Server. Detta ger i sin tur en bra möjlighet att enkelt skapa en "branch" eller "label" på kodmassan samt databasstrukturen för en specifik release. Det som jag gillar utöver detta är att om ändringen kopplas till ett "work item" i Team Foundation Server så erhåller man värdefull information om varför person X gjort tex en tabelländring. Jag gillar också att ha alla verktyg integrerade i det utvecklingsverktyg som jag arbetar dagligen i, dvs Visual Studio.

I nedanstående sida finns en kort och bra video hur man versionshanterar databasen
http://download.microsoft.com/download/d/9/d/d9d5c3e4-c0da-41b7-95db-f42422ee9a50/AddingDBtoSCC.wmv

Det finns även andra väldigt bra verktyg i "Visual Studio Team System for Database Professionals"-delen. Den innehåller tex verktygen Data Compare och Schema Compare. Dessa verktyg används för att synkronisera data eller databasstrukturen mellan tex utvecklings- till testmiljön. Företaget Red Gate har länge haft liknande verktyg men nu har Microsoft valt att försöka få med konkurrerande verktyg integrerade i Visual Studio. Jag kan varmt rekommedera dessa synkroniseringsverktyg eftersom de underlättar arbetet med publicering oerhört mycket! Väljer man att inte använda "Database Professional"-verktygen så tycker jag ändå man bör ta en titt på Red Gates SQL Compare och SQL Data Compare.

Jag hittade några kompletterande gratis verktyg för "Visual Studio Team System for Database Professionals"-delen
http://www.microsoft.com/downloads/details.aspx?FamilyID=da3f11ad-bd54-4eda-b08c-4df84df0d641&displaylang=en

Ett bra verktyg som ingår i dessa kompletterande verktyg är "Dependency Tool". Genom detta verktyg så kan man tex få en överblick över vilka beroenden och relationer en tabellkolumn har. Detta underlättar refactoringen arbetet en del.

Andra bra länkar
-
Developer Center: Visual Studio Team System for Database Professionals
- Grov översikt över verktygen i "Visual Studio Team System for Database Professionals"
- Database Professionals Team Center

Har du några andra bra tips kring "Visual Studio Team System for Database Professionals" eller annat som kan vara av intresse så hör gärna av dig till mig på krister.kauppi@elicit.se

Driftsmeddelande vid publicering

författad av Kauppi 2008-10-02 17:30

I vissa fall kan det ta tid att göra en produktionsrelease av en webbapplikation. Det är filer som ska kopieras över från test- till produktionsmiljön, databasen ska synkroniseras, script som ska köras, tjänster ska startas och stoppas m.m. Vid en produktionsrelease så kan man använda sig av ett driftsmeddelande för att informera användarna om vad som händer. I ASP.NET 2.0 så kan man skapa ett driftsmeddelande väldigt enkelt. Genom att lägga en fil vid namn app_offline.htm i webbaplikationens rotkatalogen så dirigeras alla anrop till denna sida oavsett var användaren är i applikationen. När man sedan är klar med publicering så är det bara att ändra namn på filen till tex app_offline.htm.exclude så fungerar applikationen som vanligt igen.

Här nedan kan du ladda ned ett väldigt simpelt exempel på en driftssida
http://dev.levasunt.nu/Documents/app_offline.zip

En liten brist med app_offline.htm
Oftast vill man använda sig av stylesheet filer då måste man tyvärr använda den absoluta eller relativa sökvägen för att få det att fungera. Jag skulle rekommendera att man använder den absoluta sökvägen. Detta eftersom man sällan har alla sina webbfiler i roten.

Virtualisering av förvaltningsmiljö

författad av Kauppi 2008-09-23 19:28

Ett vanligt förvaltningsproblem som jag tror många känner igen är att det inte alltid är lätt att få i ordning utvecklingsmiljön på en ny klient. Miljön kan tex kräva att vissa program och komponenter är installerade/avinstallerade, att rättigheter och andra inställningar är korrekt satta m.m. I vissa fall får man igång utvecklingsmiljön smärtfritt medan det i andra fall kan ta flera timmar för att få ordning på det. Detta trots att skapliga installationsdokument finns.

Om det sedan är en liten fix eller rättning som ska göras i ett system så kan det vara frustrerande om den mesta tiden går till att få ordning på miljön. Ansvarar man ensam för förvaltningen av ett system så är detta kanske inte ett så vanligt problem, men vad händer om man tex är på semester eller har fullt upp med annat när en akut buggrättning måste fixas av en annan person?

Ett alternativ för att hantera dylika situationer är att skapa en virtuell utvecklingsmiljö via virtualisering. Virtualisering innebär att man kan köra flera olika operativsystem på en och samma fysiska maskin. Det finns en del program för att köra och skapa virtuella miljöer. Vissa av dessa program kostar pengar medan andra är gratis. Själv har jag främst erfarenheter av Microsoft Virtual PC (VPC) vilket jag tycker fungerar bra och som är gratis.

Att virtualisera förvaltningsmiljön innebär alltså att man installerar en virtuell instans med all nödvändig programvara, komponenter och annat som krävs för att miljön ska fungera. En av de största styrkorna med virtualisering är att miljön som installerats kan kopieras mellan olika fysiska maskiner utan några större problem. Det är även möjligt att spara den på en central server så att den är åtkomlig de tillfällen den behövs. Det går också att kopiera en miljö till ett USB-minne och på detta sätt ha miljön lättillgänglig. En annan möjlighet med en virtuell instans är att det går att använda instansen som en labbmiljö när det behövs. När man sedan är klar med sina tester så är det bara att ta bort instansen och återgå till den ursprungliga instansen. Det finns mängder med andra möjligheter också. Nedan kan du läsa mer om Virtual PC samt ladda hem och testa det.

Information om Virtual PC
http://www.microsoft.com/windows/products/winfamily/virtualpc/default.mspx

Här kan du ladda ned Virtual PC 2007 helt gratis
http://www.microsoft.com/downloads/details.aspx?FamilyID=04d26402-3199-48a3-afa2-2dc0b40a73b6&displaylang=en

Saker som kan vara bra och intressenta att titta närmare på:
- Programlicenser vid virtualisering
- Versionshantera en virtuell instans
- Använda virtualisering även vid nyutveckling

Maila gärna mig på krister.kauppi@elicit.se om du har andra bra tips kring virtualisering!

Powered by BlogEngine.NET 1.4.5.0