De flesta, om inte alla, i mjukvaruvärlden känner till förkortningen SOLID. Den anspelar på fem grundläggande principer, myntade av Robert C Martin, även känd som ”Uncle Bob”. Dessa principer är ämnade att underlätta skapandet av ett mjukvarusystem som är lättunderhållet och därmed livskraftigt över tid.
För att återkoppla, så kommer här en sammanfattning av SOLID:
- Single Responsibility principle – varje klass i ett objektorienterat system ska ha ett enda ansvar, som ska vara klart avgränsat.
- Open/Closed principle – varje entitet eller klass ska vara öppet för extern utökning, men stängt för intern modifikation.
- Liskov substitution principle – ett godtyckligt objekt i ett program ska kunna ersättas med ett subobjekt, som ärver det ursprungliga objektet, utan att programmet blir inkorrekt.
- Interface segregation principle – det är bättre att hålla isär klienternas olika gränssnitt än att skapa ett enda stort allomfattande gränssnitt.
- Dependency inversion principle – entiteter och klasser ska bara bero på abstraktioner, inte på konkreta ting.
För en nybliven programmerare (eller för den delen en icke-programmerare) kan språket om klasser, gränssnitt, objekt och så vidare lätt bli svårförståeligt, men de underliggande tankarna är lättare att känna igen och hålla med i. Man kan till exempel tänka sig en fabriksrobot, som har till uppgift att packa lådor:
- Single Responsibility principle – roboten blir mindre komplicerad och fungerar bättre om den bara ska packa färdigbyggda lådor än om den ska bygga varje låda själv.
- Open/Closed principle – Om roboten inte har en funktion för att se om lådan ligger rätt, så är det mer komplicerat att bygga in det i roboten än att ställa dit en separat kamera med den funktionen och uppgiften.
- Liskov substitution principle – Om roboten kan packa en låda av en viss dimension, så ska den kunna packa alla sådana lådor oavsett om materialet är trä, plast, papp eller plåt.
- Interface segregation principle – det är mindre komplicerat att ha flera förslutningsverktyg för olika typer av lådor, än att försöka spika eller svetsa igen allihop.
- Dependency inversion principle – roboten är beroende av att lådor och innehåll levereras, men den är inte beroende av om det är en pallyft, bil eller truck som kör fram dem.
Inversion of Control och SOLID
Inversion of Control (förkortat IoC) passar väl in i SOLID, då det handlar om precis vad namnet antyder – att vända på kontrollen och därmed på beroendestrukturen. Det handlar rent konceptuellt om att en viss funktion, som är i behov av en viss resurs, ska få denna resurs tilldelad på förhand istället för att behöva skapa eller hämta den själv, som exemplet med roboten, lådorna och innehållet ovan.
Här kan det dock verka som om man bara skjuter problemet framför sig. Om roboten har möjlighet att bygga lådorna så kan den väl göra det? De måste ju ändå byggas någonstans? Det kan mycket väl se ut så på ytan, men man kan till exempel lätt inse risken för brand om roboten först ska såga material till en trälåda för att sedan, höljd i sågspån, svetsa ihop en plåtlåda. Och även om man eliminerar den risken med ett sprinklersystem, så kommer nästa komplikation när den sjöblöta roboten därpå ska packa en papplåda. Här finns det alltså en klar fördel i att låta andra maskiner, separat, bygga de olika lådorna och sedan leverera dem till packningsroboten för packning.
Säg också att man vill testa packningsfunktionen med lådor av ett billigare material, eller utan några lådor alls. Det är då långt lättare att hålla reda på vad roboten gör om man har färre steg att förhålla sig till och det är mindre risk för att ett helt packningstest går snett bara för att en bräda råkade vara skev.
Sammanfattning
Detta exempel är menat att visa tankarna bakom SOLID och IoC. För utvecklaren kommer det att klarna ytterligare när vi börjar titta ordentligt på implementationen av IoC och hur dependency injection hjälper oss att komma vidare.
Prenumerera gärna på bloggen så missar du inte nästa del, som utlovas om några veckor. Ha det gott till dess!