Välkommen till Callista Enterprise blogg - här finns tekniska artiklar, presentationer och nyheter om arkitektur och systemutveckling. Håll dig uppdaterad genom att följa oss på Twitter.
Callista Enterprise medarbetare Alexander Gunnerhell

Arkitekturblogg del 8: Fortsättning på UML – Arkitektens skruvmejsel

// Alexander Gunnerhell

I föregående inlägg i den här bloggserien om arkitektur, gick vi igenom klassdiagram.

Klassdiagram tillhör en kategori av diagram i UML som används för att beskriva olika typer av mjukvarurelaterade strukturer. På svenska kallas denna kategori av diagram ibland för statiska diagram. Strukturella/statiska UML-diagram är alltid oberoende av tid och rum.

I detta inlägg fortsätter vi med att gå igenom det ofta använda sekvensdiagrammet.

Sekvensdiagram

Sekvensdiagrammet tillhör en kategori av diagram som alla uttrycker olika former av beteende, på svenska kallas dessa ibland för dynamiska diagram.

Ett dynamiskt diagram kan vara beroende av både tid och rum. Mao: om man vill beskriva hur en mjukvarustruktur beter sig över tiden och/eller rumsligt, så väljer man något av de dynamiska diagrammen.

Allt det här med tid och rum blir snabbt abstrakt, så nu kikar vi på ett exempel:

Vi vill nu specificera att vårt hypotetiska trafikinformationssystem från del 7 i bloggserien behöver utökas med beteende (metoder) och information (attribut) som ger stöd för att hantera statistik.

Men innan vi gör detta måste vi utöka klassdiagrammet från föregående blogginlägg en aning:

Exempel 2 pa klassdiagram.png

I det utökade klassdiagrammet ovan har vi lagt till klassen ”Fordonsregister” som håller reda på alla fordon som är i tjänst samt en ”Fordonsstatistik”-klass som möjliggör att kontinuerligt hålla reda på det totala antalet passagerare på samtliga bussar som är i trafik.

Vi passar här också på att bekanta oss med två nya typer av beroenden mellan klasser:

  • ”aggregate” (aggregat på svenska) och
  • ”use” (använder på svenska)

Aggregatet mellan ”Fordonsregister” och ”Fordon” betyder här att klassen ”Fordonsregister” aggregerar (eller enklare: samlar ihop) alla ”Fordon” i vårt IT-system men att ”Fordon” existerar oberoende av om det finns ett ”Fordonsregister” eller inte. Det passar ju bra här eftersom det är så ett register brukar användas: för att samla ihop och hålla reda på olika saker och fordon brukar vanligtvis inte försvinna trots att de tas bort ur ett register ☺ ! Ett syskon till aggregatet är ”Komposition”, något du kan läsa mer om här.

”Använder”-beroendet betyder att ”Fordonsstatistik” beror av ”Fordonsregister” för att kunna fungera i systemet. ”Använder” är ett av flera beroenden som tillhör kategorin ”Beroende”-associationer (dependency på engelska). Vi kommer inte att fördjupa oss i denna kategori i detta blogginlägg men för den som vill veta mer är Wikipedia alltid en bra start!

Det vi nu vill göra är förstås att specificera hur vi tänker oss att systemet kontinuerligt skall hålla reda på det totala antalet passagerare på alla bussar som är i tjänst, dvs systemets beteende beskrivet i form av ett sekvensdiagram:

Annoterat sekvensdiagram.png

Här händer det en massa saker! Låt oss börja med de grundläggande ”byggstenarna” i sekvensdiagrammet innan vi går igenom själva beteendet eller flödet:

  • Aktörer: användare eller system som inte är en del av vårt system men som interagerar med vårt system, här i form av passagerarsensorer i respektive buss och en extern timer (längst upp till höger i diagrammet)
  • Instans: unika representationer i vårt system av olika klasser av företeelser, tex ”enStatistikhanterare”, ”enBlåBuss”, etc…
  • Livslinje: hur länge (tidsdimensionen!) instanser finns tillgängliga för anrop i systemet
  • Aktivering: den exekvering (rumsdimensionen!) som sker i respektive instans som en följd av ett givet meddelande
  • Synkront meddelandeutbyte: exekveringen i den anropande instansen stannar tills denna fått ett svar från den anropade instansen
  • Asynkront meddelande: exekveringen i den anropande instansen fortsätter utan att denna fått ett svar från den anropade instansen (i detta fall är det t.o.m. så att den anropande instansen inte behöver få ett svar överhuvudtaget)
  • Fragment: uttrycker olika typer av flödeskontroll för ett eller flera meddelandeutbyten (oftast flera), tex repetitionsflöden (loopar), alternativa flöden, flödesavbrott, etc…

Låt oss nu gå igenom vad som händer i systemet för att hålla reda på statistiken om det totala antalet passagerare på bussar som är i tjänst (siffrorna i varje punkt refererar till meddelandeid:na i sekvensdiagrammet)!

1,3,5) Instanserna:

  • ”enBlåBuss” av klassen ”Buss”,
  • ”enRödBuss” av klassen ”Buss” och
  • ”enGrönLastbil” av klassen ”Lastbil”

registrerar sig hos instansen ”ettRegister” i och med att dessa tas i tjänst. Detta sker genom anrop till metoden ”taFordonITjänst(ettFordon : Fordon) i instansen ”ettRegister”. Eftersom både bussar och lastbilar är ett slags fordon så går det utmärkt att skicka med en instans av klassen ”Buss” till en metod som förväntar sig instanser av klassen ”Fordon”.

2,4) Aktörerna:

  • ”passagerarSensorBlåBuss” och
  • ”passagerarSensorRödBuss”

registrerar de första påstigande passagerarna på respektive buss och anropar asynkront instanserna:

  • ”enBlåBuss” och
  • ”enRödBuss”

via meddelandena ”ändraAntalPassagerare(nyttAntalPassagerare : int = 9)” samt ”ändraAntalPassagerare(nyttAntalPassagerare : int = 3)”.

6) Aktören ”timer” anropar asynkront instansen ”enStatistikhanterare” via metoden ”uppdateraTotaltAntalPassagerare”, detta för att tala om för systemet att det är dags att uppdatera statistiken.

6.1) Instansen ”enStatistikhanterare” anropar sig själv för att nollställa attributet ”totaltAntalPassagerare” via metoden ”nollställTotaltAntalPassagerare()”. Därefter börjar denna iterera över alla fordon som är i tjänst i fordonsregistret (fragmentet ”loop”)

6.2) Instansen ”enStatistikhanterare” anropar instansen ”ettRegister” för att kontrollera om det finns något fordon kvar att behandla i ”ettRegister”, detta sker via metoden ”harEttTillFordonITjänst() : boolean”. Finns det fordon kvar i ”ettRegister” så är svaret på anropet true (sant) annars är det false (falskt).

Detta anrop sker i fragmentet ”break” som är ett fragment inuti fragmentet ”loop”. Innebörden av ”break” är att om fragmentets styrvillkor är true (sant) så avbryts exekveringen i det omslutande fragmentet ”loop”. Är det false (falskt) så fortsätter exekveringen i det omgivande fragmentet ”loop”.

6.4) Instansen ”enStatistikhanterare” hämtar nästa fordon i fordonsregistret genom att anropa metoden ”hämtaNästaFordonITjänst() : Fordon” i instansen ”ettRegister”. Svaret blir en referens till fordonet som vi placerar i attributet ”aktuelltFordonITjänst” av klassen ”Fordon”.

6.5) Om ”aktuelltFordonITjänst” refererar till en instans av klassen ”Buss”, så skapar instansen ”enStatistikhanterare” referensen ”aktuellBussITjänst” till denna instans. Om ”aktuelltFordonITjänst” refererar till en instans av någon annan klass än ”Buss”, så händer inget mer i denna del av iterationen utan exekveringen fortsätter i 6.2) ovan.

Allt detta sker genom att meddelandeutbytena 6.5, 6.6 och 6.8 placerats i fragmentet ”alt” med styrvillkoret ”aktuelltFordonITjänst är en Buss”

6.6) Om ”aktuelltFordonITjänst” refererar till en instans av klassen ”Buss”, så hämtar ”enStatistikhanterare” antal passagerare i den aktuella bussen via metoden ”hämtaAntalPassagerare() : int”.

6.8) Om ”aktuelltFordonITjänst” refererar till en instans av klassen ”Buss”, så adderar ”enStatistikhanterare” antalet passagerare till det totala antalet passagerare genom att anropa sig själv via metoden ”adderaTillTotaltantalPassagerare(operand : long)”.

Därefter börjar iterationen om i steg 6.2) ovan.

Slutord

Då har vi gått igenom de två vanligaste UML-diagrammen, klassdiagrammet som är ett exempel på ett statiskt diagram och sekvensdiagrammet som är ett exempel på ett dynamiskt diagram.

Med detta avslutar vi det här blogginlägget och i och med det även den här bloggserien kring grunderna i IT-arkitektur. För den som vill lära sig mer om UML så är, som alltid, Wikipedia en bra start!

Arkitekturbloggen kommer däremot att leva kvar och vi kommer fortsätta att publicera material kring olika områden inom IT-arkitektur, väl mött i en snar framtid!

Tack för att du läser Callista Enterprise blogg.
Hjälp oss att nå ut med information genom att dela nyheter och artiklar i ditt nätverk.

Kommentarer