Callista Enterprise medarbetare Patrik Gustavsson

Arkitekturblogg del 6: Integrationsmönster och designmönster

// Patrik Gustavsson

I slutet av förra inlägget i den här bloggserien om arkitektur så utlovades att nästa inlägg ska ha följande innehåll: ”Integrationsmönster och designmönster. I samband med det finns det även anledning att titta lite närmare på den roll som arkitekten har.” Det är tre helt olika ämnen så det är på sin plats med en motivering varför jag valde just dessa tre.

Återigen vill jag därför påminna om den definition av mjukvaruarkitektur som den här bloggserien utgår ifrån.

arkblogg 6 1.png

”The software architecture of a system is the set of structures needed to reason about the system, which comprise software elements, relations among them, and properties of both”

Vi har i tidigare inlägg i bloggserien lärt oss vilka faktorer och omständigheter som har påverkan på arkitekturen och även hur man med hjälp av taktiker och mönster som arkitekt kan forma arkitekturen. Vi har alltså lärt oss hur man kommer fram till de mjukvaruelement som behövs och hur de är relaterade till varandra med sina olika ansvarsområden. Det är därför helt naturligt att vi nu tittar på en typ av mönster som kan användas mellan olika mjukvaruelement (integrationsmönster) och en typ av mönster som kan användas inom ett mjukvaruelement (designmönster).

Några ord om arkitektens roll

När vi tittar på bilden ovan som beskriver definitionen av mjukvaruarkitektur så inser vi också att en mjukvaruarkitekt har mutat in olika områden där arbete kan bedrivas. Några designers, utvecklare och testare kanske arbetar med ett mjukvaruelement samtidigt som några andra arbetar med ett eller ett par andra mjukvaruelement. Samtidigt arbetar någon med integrationslösningar mellan mjukvaruelementen och inom de olika områdena råder en viss frihet att ta egna designbeslut.

En arkitekt behöver inte (och ska heller inte) lägga sig i alla detaljer inom ett mjukvaruelement eller i samarbetet mellan dem. Det finns även en rent psykologisk aspekt av den delen som inte ska underskattas. Jag tror nämligen att de flesta människor som arbetar med utveckling av mjukvara vill känna sig delaktiga i den kreativa process som arbetet innebär. Därför är det bara bra att lösningar inte tas fram i minsta detalj utan snarare som olika områden där viss frihet till egna designbeslut kan tas.

Integrationsmönster

När man inom IT hör ordet integration så går tankarna nästan direkt till att olika system och lösningar utbyter information med varandra. Men integration handlar egentligen om att ge en upplevd helhet (jfr ord som ’Integer’ och ’Integral’ på Engelska med ordet integration. Latinskt ursprung är ordet ’Integra’ som betyder ungefär: helhet, att vara hel). Men det är sant att den upplevda helheten inom mjukvara nästan alltid kommer sig av utbyten av information mellan olika delar av en lösning. Upplevd helhet kan ibland uppnås i portalliknande lösningar där man utan att byta ut information visar upp information från olika källor i samma användargränssnitt. De mönster som tas upp i denna bloggpost handlar om att skapa helhet med hjälp av informationsutbyte. Integrationsmonster.png

Dessa integrationsmönstren finns beskrivna i den utmärkta bok som finns på bilden – Enterprise Integration Patterns av Gregor Hohpe and Bobby Woolf. Mönstren (65 stycken) finns även beskrivna på bokens hemsida.

”Integration styles”

Det finns egentligen bara fyra stycken tillvägagångssätt för integration och bilder som illustrerar dem följer nedan.

  • Filöverföring
  • Gemensam databas
  • Anrop av API funktioner (ex WS) som tillhandahålls av en applikation
  • Utbyte av meddelanden mellan applikationer

Filöverföring

monster1.png Bilden visar hur applikation A skapar en fil som sedan läses in i applikation B. Efter inläsning finns den information som stod i filen tillgänglig för applikation B. Det är vanligt att man föder till exempel ekonomisystem med information på det här sättet. Man ska inte blanda ihop integration med hjälp av filöverföring med den kvalitetsegenskap som handlar om samarbetsförmåga (interoperability). Integration med filöverföring är något man gör men samarbetsförmåga är något man har. På min Mac dator finns program som jag kan skapa presentationer med och om jag vill så kan jag spara presentationerna i samma format som Microsoft PowerPoint. Det innebär att programmet jag använder har en hög grad av samarbetsförmåga. Men det är inte alls samma sak som att ha en uppsatt integration. Filöverföring är mindre lämpligt att använda om applikation A och applikation B båda två behöver ändra informationen. Filöverföring är bäst lämpad för att överföra färdig information från ett system till ett annat.

Gemensam databas

Monster2.png Bilden visar hur några applikationer har tillgång till samma information eftersom de alla lagrar och hämtar i samma databas. Det finns en hel del skrivet om när det är lämpligt eller inte att integrera på det här sättet och den intresserade kan hitta mycket information om det på Internet. Men oavsett vad man har för inställning till det här tillvägagångssättet för integration så är det ett av de fyra möjliga tillvägagångssätten och tas därför upp här.

Anrop av API funktioner som tillhandahålls av en applikation

Monster3.png Ett mycket vanligt sätt att integrera applikationer är att applikation B tillhandahåller olika gränssnitt för funktioner som applikation A kan anropa. Webservices är ett populärt sätt att hantera själva gränssnitten. En intressant sak är att API funktioner ger inte bara möjlighet att skicka information mellan applikation A och applikation B. En anropad funktion behöver inte bara ta emot information utan den kan även utföra saker.  

Utbyte av meddelanden mellan applikationer

Monster41.png Meddelanden mellan applikationer ger en stor frihet till integrationer och en applikation behöver inte ens nödvändigtvis känna till vilka andra applikationer som tar emot meddelandena. En applikation kan med ett meddelande informera om en händelse och de applikationer som behöver känna till den händelsen är på förhand konfigurerade till att ta emot meddelanden avseende den typen av händelser. Själva meddelandena (ofta givna på XML format) innehåller den information som ingår meddelandet. I bilden visas hur meddelanden transporteras med en meddelandebuss. Det går även att skicka meddelanden mellan applikationer enbart med hjälp av en köhanterare som exempelvis MQSeries från IBM eller MSMQ från Microsoft.  

Ett par exempel på integrationsmönster

Oversiktsbild.png Som den här översiktsbilden visar (även den från Enterprise Integration Patterns ) så finns det ett ganska stort antal integrationsmönster insorterade inom olika kategorier. Eftersom dessa finns beskrivna både i boken och på nätet så ger jag bara ett par exempel på integrationsmönster här och lämnar till den som vill att studera saken närmare att göra det på egen hand på ovanstående länk eller direkt i boken.

Hur kan vi utföra komplex hantering på ett meddelande och ändå upprätthålla oberoende och flexibilitet? meddelande1.png

Känns mönstret igen? Jag hoppas det, för det är exakt ett av de mönster som Mary Shaw identifierade och beskrev som ett arkitekturmönster (som vi tittade på i föregående blogginlägg).

Hur kan vi skicka meddelanden genom ett antal olika bearbetningssteg när stegen inte är kända under design-time och även kan variera från meddelande till meddelande? meddelande2.png

Routing Slip är ett mönster som jag gillar och det går helt enkelt ut på att du till själva meddelandet lägger till information om var det ska skickas och i vilken ordning. En ”routing slip” är då att betrakta ungefär som en fraktsedel som bestämmer vart ett paket ska skickas.

Förutom de fyra olika tillvägagångssätten för integration och de olika mönstren för integration (och de kategorier som de ingår i) så är det bra att även känna till grundbegrepp som message, queue, topic, channel osv.  

Designmönster

designspattens.png

Den här boken är en klassiker och skrevs av fyra personer som ibland kallas för ”Gang of Four”. Den har många år på nacken men de designmönster som den tar upp är fortfarande i hög grad aktuella och jag kan varmt rekommendera boken. På samma sätt som vi såg att arkitekturmönstren som Mary Shaw beskrev fortfarande är aktuella så är designmönstren som den här boken tar upp fortfarande aktuella. Båda typer av mönster är oberoende av teknik och är därför inte benägna att behöva ändras så ofta. Det handlar oftare om att mönster kan tillkomma snarare än att mönster blir inaktuella. Boken har kategoriserat in designmönstren i tre olika kategorier.

  • Creational
  • Structural
  • Behaviour

För att förstå designmönster så behöver man även förstå grundkoncept som klass och objekt. Det är begrepp som visserligen är ganska programmeringsnära men ändå helt nödvändiga att förstå när vi i senare inlägg tittar på modelleringsspråket UML.

En klass är helt enkelt ett grundbegrepp som exempelvis Person eller Bok. Personer har ett antal gemensamma egenskaper och böcker har även de ett antal gemensamma egenskaper. Exempelvis så har alla personer ett personnummer och ett efternamn. På samma sätt har alla böcker en författare (som är en person).

Utgående från klasser kan man sedan tala om ”objekt” som är specifika instanser av klasser. Boken ”The Fellowship of the Ring” har ”JRR Tolkien” som författare och boken ”Emil i Lönneberga” har ”Astrid Lindgren” som författare. Både JRR Tolkien och Astrid Lindgren har personnummer och efternamn. Det är alltså inte själva egenskaperna som är lika mellan olika objekt i en klass utan själva uppsättningen av egenskaper. Dvs även om ”Lindgren” och ”Tolkien” är helt olika efternamn så hör båda två till klassen Person och de har båda två egenskapen att de har ett efternamn.

I början av det här blogginlägget skrev jag att designmönster används inom ett mjukvaruelement. Hur kan vi vara säkra på det? Jo, det är helt enkelt för att designmönster handlar om objekt (hur de skapas, hanteras osv) och när du skapar ett objekt (det sker alltid baserat på en klass) så sker det direkt i internminnet där den kod körs där du skapar objektet, inte i någon annan mjukvara som kör någonstans. kodexempel.png

Ovan visas lite kod (från Engelskspråkiga Wikipedia) som visar exempel på det kanske mest grundläggande designmönstret – Singleton. Syftet med en Singleton är säkerställa att man bara skapar en enda instans av en klass. Ett exempel på det kan vara en klass som hanterar loggning och som är tänkt att användas av hela applikationen. Singleton ingår i kategorin ”Creational patterns” eftersom det handlar om skapandet av ett objekt.

Det som sker i koden är följande:

  • Om det var tillåtet att skapa nya instanser med new från andra delar av koden så kan du vara ganska säker på att någon råkar skapa en andra instans av din Singleton. Därför sätts konstruktorn till private vilket förhindrar just det.
  • Istället för new så måste det finnas andra sätt att få tag på den instans som finns av klassen. Metoden som heter getInstance() returnerar alltid samma instans som finns sparad i en medlemsvariabel som i exemplet heter INSTANCE. Det är därför alla som anropar getInstance() metoden garanterat alltid får samma instans.
  • Metoden getInstance() och medlemsvariablen INSTANCE är båda definierade som static och det löser ett problem som kan jämställas med det klassiska hönan-och-ägget problemet. Hur ska du kunna anropa getInstance på ett Singleton om du inte redan har en instans av en Singleton att anropa? Static innebär i det här fallet att metoden och instansvariablen är samma oavsett instans och därför kan du anropa getInstance utgående från klassen och behöver inte redan en instans (ett objekt baserat på klassen) för att göra det anropet.

Nästkommande inlägg

Nu har bloggserien kommit till ett läge där det är lämpligt att titta på det mest använda språket för att rita mjukvaruarkitektur med bilder – ”The Unified Modelling Language”.

Nästa inlägg kommer att beskriva vilka typer av UML diagram som finns och hur de är kategoriserade. Naturligtvis kommer jag i beskrivningen av dem att fokusera mest på de som används oftast.

Förutom att gå igenom de olika typerna av diagram som finns så kommer jag också att beskriva vilka diagram som är bäst lämpade i förhållande till olika delar av arbetet med mjukvaruutvecklingen.

Kommentarer