Tämä esimerkki näyttää, miten oppilasrekisterin toiminnallinen määrittely etenee tekniseksi määrittelyksi. Samalla se havainnollistaa, miten kaavioita tehdään Mermaidilla. Kuvattu sovellus on tarkoituksella yksinkertaistettu, jotta määrittelyjen ja kaavioiden yhteys on helppo nähdä. Tässä esimerkissä tarkastelu rajataan opiskelijan käyttämiin toimintoihin.
Sivua voi käyttää myös oman määrittelyn oppaana: kuvaa ensin tarve ja vaatimukset, havainnollista niitä sopivilla kaavioilla ja suunnittele vasta sitten toteutus. Kaikki projektit eivät tarvitse kaikkia tässä esitettyjä kaavioita. Valitse ne, jotka auttavat ymmärtämään juuri oman järjestelmäsi toimintaa tai rakennetta. Kaavioiden Mermaid-koodit voi avata niiden alta.
Vaatimusmäärittelylle ja tekniselle määrittelylle ei ole yhtä kaikkialla käytettyä alaotsikkorakennetta. Organisaatiolla, asiakkaalla tai oppilaitoksella voi olla oma dokumenttipohjansa. Tässä esitetty otsikointi on yksi mahdollinen tapa jäsentää sisältö. Sovella rakennetta projektin tarpeisiin ja mahdolliseen annettuun dokumenttipohjaan. Olennaista on, että tarvittavat asiat kuvataan selkeästi ja ristiriidattomasti.
Tässä ohjelmoijien opetukseen tarkoitetussa oppaassa käytetään myös kaavioiden nimiä otsikkoina, jotta kaaviotyypit ja niiden esimerkit löytyvät helposti. Samalla opit yhdistämään kaavion nimen sen tarkoitukseen. Voit käyttää omassa dokumentissasi samaa tapaa tai nimetä luvut käsiteltävän asian mukaan. Otsikkoa voi myös täsmentää, esimerkiksi ”Käyttöönottokaavio : sovelluksen sijoittuminen”, ”Viestiyhteyskaavio : kirjautuminen” tai ”Luokkakaavio : Qt-sovelluksen rakenne”.
Kerro kaavion yhteydessä lyhyesti, mitä se kuvaa juuri tässä järjestelmässä, ja selitä tarvittavat ratkaisut ja perustelut. Kaikkien alaotsikoiden ei tarvitse olla kaavioiden nimiä: esimerkiksi tavoitteet ja rajaus, hyväksymiskriteerit sekä rajapintojen kuvaukset tarvitsevat myös sanallista käsittelyä.
Kaavioiden selitteet ja toimintojen kuvaukset ovat suomeksi. Toteutuksen tunnisteet, kuten luokkien, moduulien, muuttujien, metodien ja tietokantataulujen nimet, ovat englanniksi. Myös Mermaid-koodin tunnisteet ovat englanniksi, vaikka kaaviossa näkyvä selite olisi suomeksi.
> Muistutus: Määrittelyvaiheessa kerrotaan, MITÄ tehdään, ja suunnitteluvaiheessa, MITEN tehdään.
Toiminnallinen määrittely kuvaa asiakkaan ja käyttäjän näkökulmasta, mitä järjestelmän pitää tehdä. Tässä vaiheessa kuvataan toiminnot ja käyttöliittymän perusidea ilman teknisiä toteutusvalintoja.
Vaatimusmäärittely on tätä laajempi kokonaisuus: siihen kuuluvat myös tavoitteet, rajaus, käyttöoikeudet, laatuvaatimukset ja hyväksymiskriteerit. Kaaviot täydentävät sanallisia vaatimuksia. Ne eivät yksin kerro esimerkiksi sitä, kuka saa nähdä henkilötiedot tai miten onnistunut toteutus todetaan.
Aloita kertomalla, mikä ongelma ratkaistaan ja keitä ratkaisu palvelee. Tämän esimerkin tavoitteena on, että opiskelija voi tarkistaa omat tietonsa ja ilmoittautua kursseille itsenäisesti. Käyttäjä on opiskelija ja oppilaitos puolestaan määrittelee, mitä tietoja ja kursseja palvelussa tarjotaan.
Tässä rajauksessa mukana ovat kirjautuminen, uloskirjautuminen, istunnon vanheneminen, omien henkilötietojen ja arvosanojen katselu sekä kurssille ilmoittautuminen. Arvosanojen syöttäminen, opiskelijatietojen ylläpito ja maksaminen jäävät esimerkin ulkopuolelle. Oletuksena on, että opiskelija-, kurssi- ja suoritustiedot ovat jo olemassa. Kirjaa vastaavat oletukset omaan määrittelyysi ja varmista ne tilaajalta.
Anna tärkeille vaatimuksille tunnisteet, jotta niihin voi viitata suunnittelussa ja testauksessa. Kirjoita jokainen vaatimus niin täsmällisesti, että sen toteutuminen voidaan todentaa. Hyväksymiskriteeri kertoo, millä havaittavalla tuloksella vaatimus katsotaan täytetyksi.
Laatuvaatimuksia voivat olla myös käytettävyys, saavutettavuus ja saatavuus. Valitse projektillesi olennaiset vaatimukset ja sovi niiden tärkeys tilaajan kanssa. Yllä olevat tavoitteet ovat opetusesimerkin valintoja, eivät kaikkien järjestelmien yleisiä raja-arvoja.
Sovellukseen toteutetaan seuraavat toiminnot:
Tämä yleistasoinen kaavio näyttää, että opiskelija käyttää oppilasrekisteriä omalla laitteellaan verkkoyhteyden kautta. Se ei vielä määrittele sovelluksen toteutusteknologioita eikä palveluympäristön sisäistä rakennetta. Kaavio on havainnollistettu Mermaidin vuokaaviosyntaksilla.
flowchart LR
subgraph StudentDevice["Opiskelijan laite"]
UserInterface["Oppilasrekisterin käyttöliittymä"]
end
subgraph ServiceEnvironment["Palveluympäristö"]
RegistryService["Oppilasrekisteri"]
end
UserInterface <-->|"Verkkoyhteys"| RegistryService```mermaid
flowchart LR
subgraph StudentDevice["Opiskelijan laite"]
UserInterface["Oppilasrekisterin käyttöliittymä"]
end
subgraph ServiceEnvironment["Palveluympäristö"]
RegistryService["Oppilasrekisteri"]
end
UserInterface <-->|"Verkkoyhteys"| RegistryService
```Käyttötapauskaavio kokoaa käyttäjän tavoitteet ja järjestelmän tarjoamat toiminnot. Aloita tunnistamalla käyttäjäroolit ja se, mitä kukin haluaa saada aikaan. Tarkemmat etenemisvaiheet ja poikkeukset kuvataan käyttötapauskorteissa.
usecase-beta
direction LR
actor Student("Opiskelija")
systemBoundary Application["Oppilasrekisteri"]
Login("Kirjaudu sisään")
ViewInfo("Katso henkilötiedot")
ViewGrades("Katso arvosanat")
RegisterCourse("Ilmoittaudu kurssille")
Logout("Kirjaudu ulos")
end
Student --> Login
Student --> ViewInfo
Student --> ViewGrades
Student --> RegisterCourse
Student --> Logout
ViewInfo ..> : include Login
ViewGrades ..> : include Login
RegisterCourse ..> : include Login```mermaid
usecase-beta
direction LR
actor Student("Opiskelija")
systemBoundary Application["Oppilasrekisteri"]
Login("Kirjaudu sisään")
ViewInfo("Katso henkilötiedot")
ViewGrades("Katso arvosanat")
RegisterCourse("Ilmoittaudu kurssille")
Logout("Kirjaudu ulos")
end
Student --> Login
Student --> ViewInfo
Student --> ViewGrades
Student --> RegisterCourse
Student --> Logout
ViewInfo ..> : include Login
ViewGrades ..> : include Login
RegisterCourse ..> : include Login
```Kaavio näyttää kirjautumisen ja sitä seuraavan toimintovalinnan opiskelijan näkökulmasta. Oppilasrekisteri esitetään yhtenä kokonaisuutena, joten kaavio ei vielä ota kantaa käyttöliittymän, rajapinnan tai tietojen tallennuksen toteutukseen. Viestiyhteyskaavio näyttää, mitä viestejä osapuolet lähettävät toisilleen tapahtumien aikana.
sequenceDiagram
actor Student as Opiskelija
participant Registry as Oppilasrekisteri
Student->>Registry: Kirjautuu
alt Kirjautuminen onnistuu
Registry-->>Student: Näyttää valikon
alt Henkilötietojen katselu
Student->>Registry: Valitsee henkilötiedot
Registry-->>Student: Näyttää henkilötiedot
else Arvosanojen katselu
Student->>Registry: Valitsee arvosanat
Registry-->>Student: Näyttää arvosanat
else Kurssille ilmoittautuminen
Student->>Registry: Valitsee kurssin ja ilmoittautuu
Registry-->>Student: Näyttää vahvistuksen
end
else Kirjautuminen epäonnistuu
Registry-->>Student: Näyttää kirjautumisen uudelleen
end```mermaid
sequenceDiagram
actor Student as Opiskelija
participant Registry as Oppilasrekisteri
Student->>Registry: Kirjautuu
alt Kirjautuminen onnistuu
Registry-->>Student: Näyttää valikon
alt Henkilötietojen katselu
Student->>Registry: Valitsee henkilötiedot
Registry-->>Student: Näyttää henkilötiedot
else Arvosanojen katselu
Student->>Registry: Valitsee arvosanat
Registry-->>Student: Näyttää arvosanat
else Kurssille ilmoittautuminen
Student->>Registry: Valitsee kurssin ja ilmoittautuu
Registry-->>Student: Näyttää vahvistuksen
end
else Kirjautuminen epäonnistuu
Registry-->>Student: Näyttää kirjautumisen uudelleen
end
```Tilakaavio kuvaa yhden kohteen mahdolliset tilat ja tapahtumat, jotka siirtävät sen tilasta toiseen. Samasta sovelluksesta voidaan laatia useita tilakaavioita eri kohteille. Laadi kaavioita tarpeen mukaan ja kerro kunkin yhteydessä, mitä kohdetta se kuvaa.
Tässä kohteena on käyttäjän kirjautuminen ja istunto: opiskelija on joko kirjautumatta, odottaa kirjautumisen tarkistusta tai on kirjautunut. Tilakaavio täydentää vaatimuksia V-03–V-05.
Tilojen nimet kertovat tilanteen ja nuolten tekstit siirtymän aiheuttavan tapahtuman. Musta alkupiste osoittaa alkutilan. Lopputilaa ei tarvita, koska opiskelija voi kirjautua uudelleen. Henkilötietojen katselu, arvosanojen katselu ja kurssille ilmoittautuminen tapahtuvat Kirjautunut-tilassa, mutta näkymän vaihtaminen ei itsessään muuta kirjautumisen tilaa.
stateDiagram-v2
state "Ei kirjautunut" as LoggedOut
state "Kirjautuminen<br/>tarkistetaan" as CheckingLogin
state "Kirjautunut" as LoggedIn
[*] --> LoggedOut
LoggedOut --> CheckingLogin: Opiskelija lähettää tunnukset
CheckingLogin --> LoggedIn: Tunnukset hyväksytään
CheckingLogin --> LoggedOut: Tunnukset hylätään
CheckingLogin --> LoggedOut: Tarkistus epäonnistuu
LoggedIn --> LoggedOut: Opiskelija kirjautuu ulos
LoggedIn --> LoggedOut: Istunnon voimassaoloaika päättyy```mermaid
stateDiagram-v2
state "Ei kirjautunut" as LoggedOut
state "Kirjautuminen<br/>tarkistetaan" as CheckingLogin
state "Kirjautunut" as LoggedIn
[*] --> LoggedOut
LoggedOut --> CheckingLogin: Opiskelija lähettää tunnukset
CheckingLogin --> LoggedIn: Tunnukset hyväksytään
CheckingLogin --> LoggedOut: Tunnukset hylätään
CheckingLogin --> LoggedOut: Tarkistus epäonnistuu
LoggedIn --> LoggedOut: Opiskelija kirjautuu ulos
LoggedIn --> LoggedOut: Istunnon voimassaoloaika päättyy
```Kustakin olennaisesta käyttötapauksesta laaditaan yleensä oma käyttötapauskortti, jossa kuvataan toiminnon tavoite, eteneminen ja poikkeukset tarkemmin kuin käyttötapauskaaviossa. Tässä esitetään malliksi vain yksi kortti, joka vastaa kaavion "Ilmoittaudu kurssille" -käyttötapausta.
| TUNNISTE | KT-0001 | VERSIO | 1.0 |
|---|---|---|---|
| NIMI | Ilmoittaudu kurssille | ||
| SUORITTAJAT | Opiskelija, oppilasrekisteri | ||
| TAVOITE | Opiskelija ilmoittautuu valitsemalleen kurssille. | ||
| ESIEHDOT | Opiskelija on kirjautunut sovellukseen ja järjestelmässä on ilmoittautumiseen tarjolla oleva kurssi. | ||
| KUVAUS |
1. Opiskelija valitsee valikosta kurssille ilmoittautumisen. 2. Järjestelmä näyttää ilmoittautumiseen tarjolla olevat kurssit. 3. Opiskelija valitsee kurssin ja painaa Ilmoittaudu-painiketta. 4. Järjestelmä tallentaa opiskelijan ilmoittautumisen. (P1) 5. Järjestelmä näyttää vahvistuksen ilmoittautumisesta. |
||
| LOPPUEHDOT | Ilmoittautuminen on tallennettu ja opiskelija on saanut vahvistuksen. | ||
| POIKKEUKSET | P1: Tallennus epäonnistuu – järjestelmä ilmoittaa virheestä eikä näytä onnistumisvahvistusta. | ||
| AVOIMET ASIAT | Voiko opiskelija perua ilmoittautumisensa myöhemmin? | ||
Käyttötapausten pohjalta voidaan luonnostella sovelluksen näkymät. Onnistunut kirjautuminen avaa StudentInfo-valikon, josta opiskelija siirtyy haluamaansa toimintoon. Epäonnistuneen kirjautumisen jälkeen pysytään Login-näkymässä. Uloskirjautuminen palauttaa Login-näkymään. Myös vanhentuneen istunnon havaitseminen palauttaa tähän näkymään ja poistaa aiemmin näytetyt opiskelijan tiedot.
Mermaid ei sovellu varsinaisten käyttöliittymänäkymien luonnosteluun, vaikka sillä voi kuvata näkymien välisen kulun. Luonnokset voi piirtää esimerkiksi Excalidrawilla osoitteessa https://excalidraw.com/ ja ladata PNG- tai SVG-kuvatiedostoina. Alla olevat esimerkkinäkymät on hahmoteltu HTML:llä ja CSS:llä.
Näkymät ovat karkeita luonnoksia. Kentät ja painikkeet näyttävät suunnitellun sisällön ja kulun.
Virheellinen kirjautuminen palauttaa tähän näkymään.
Valitse, mitä haluat tehdä:
Onnistunut ilmoittautuminen vahvistetaan tässä näkymässä.
Tekninen määrittely kuvaa, miten toiminnallisessa määrittelyssä kuvatut toiminnot toteutetaan. Tässä esimerkissä valitaan sovelluksen osat, niiden välinen viestintä, luokkarakenne ja tietokannan rakenne.
Pidä vaatimusten tunnisteet mukana suunnittelussa. Näin toteutusratkaisulle löytyy peruste ja jokaiselle vaatimukselle voidaan suunnitella testi. Esimerkiksi vaatimus V-01 tarkentuu seuraavasti:
Tämä tarkentaa jäljempänä esitettyjä yleistasoisia kaavioita. Kuvaa omassa teknisessä määrittelyssäsi myös rajapintojen pyyntöjen ja vastausten tietosisältö sekä muut olennaiset virhevastaukset. Pelkkä nuoli osien välillä ei vielä määrittele niiden välistä sopimusta.
Vaatimusmäärittelyn tilakaavio ohjaa myös kirjautumisen teknistä toteutusta. Vaatimuksen V-03 mukaisesti Qt-käyttöliittymä odottaa kirjautumispyynnön vastausta ja avaa StudentInfo-näkymän vasta onnistuneen vastauksen jälkeen. Hylätyt tunnukset, yhteysvirhe tai pyynnön aikakatkaisu palauttavat kirjautumisnäkymän tilaan, jossa opiskelija voi yrittää uudelleen. Vaatimuksen V-04 mukaisesti uloskirjautuminen poistaa asiakkaan muistista kirjautumistunnisteen ja opiskelijan tiedot sekä sulkee suojatut näkymät. Vaatimuksen V-05 mukaisesti palvelin tarkistaa kirjautumistunnisteen voimassaolon jokaisella suojatulla pyynnöllä. Vanhentunut tunniste tuottaa HTTP 401 -vastauksen, jolloin käyttöliittymä tyhjentää kirjautumistiedot ja palaa Login-näkymään. Täsmennä teknisessä määrittelyssä tunnisteen voimassaoloaika sovitun vaatimuksen mukaan sekä se, miten tunniste mitätöidään palvelimella, jos uloskirjautumisen halutaan estävän myös aiemmin kopioidun tunnisteen käytön.
Kirjaa keskeisistä ratkaisuista, mitä valittiin ja miksi. Tässä Qt-asiakas ja Node.js-rajapinta ovat opetusesimerkin teknologiavalintoja. Rajapinta keskittää käyttöoikeuksien tarkistamisen palvelimelle, ja relaatiotietokanta sopii opiskelijoiden, kurssien ja ilmoittautumisten välisten suhteiden tallentamiseen. Omassa projektissa perusteluja voivat olla myös kohdeympäristö, ylläpidettävyys ja tiimin osaaminen.
Sovi lisäksi tietojen validointi, virheiden käsittely ja tallennuksen eheys. Jos samalle kurssille saa ilmoittautua vain kerran, sääntö pitää ensin hyväksyä vaatimukseksi ja sen jälkeen toteuttaa esimerkiksi opiskelijan ja kurssin yhdistelmän yksikäsitteisyysrajoitteella. Tekninen ratkaisu ei saa huomaamatta päättää käyttäjää koskevaa toimintasääntöä.
Käyttöönottokaavio näyttää, missä laitteissa sovelluksen osat toimivat ja miten ne ovat yhteydessä toisiinsa. Asiakassovellus toteutetaan C++:lla ja Qt:lla, REST-rajapinta Node.js:llä ja Expressillä. Tiedot tallennetaan MySQL-tietokantaan. Kaavio on havainnollistettu Mermaidin vuokaaviosyntaksilla.
flowchart LR
subgraph ClientMachine["Asiakkaan laite"]
QtApp["Qt-sovellus (C++)"]
end
subgraph Server["Palvelin"]
RestAPI["REST-rajapinta (Node.js / Express)"]
Database[("StudentDb (MySQL)")]
end
QtApp <-->|"HTTPS / JSON"| RestAPI
RestAPI <-->|"MySQL-protokolla"| Database```mermaid
flowchart LR
subgraph ClientMachine["Asiakkaan laite"]
QtApp["Qt-sovellus (C++)"]
end
subgraph Server["Palvelin"]
RestAPI["REST-rajapinta (Node.js / Express)"]
Database[("StudentDb (MySQL)")]
end
QtApp <-->|"HTTPS / JSON"| RestAPI
RestAPI <-->|"MySQL-protokolla"| Database
```Qt-sovellus ja REST-rajapinta voidaan tässä tulkita ohjelmiston pääkomponenteiksi. MySQL-laatikko kuvaa niiden käyttämää tietokantaa, joka ei itsessään ole ohjelmistokomponentti. Sisäiset laatikot kuvaavat esimerkiksi näkymiä ja moduuleja. Mermaidin vuokaaviosyntaksilla tehty kuva havainnollistaa osien riippuvuuksia, mutta ei noudata UML-komponenttikaavion merkintöjä täsmällisesti.
Toteutuksessa on valittu MVC-mallia mukaileva työnjako: Qt-sovellus toteuttaa näkymät (View), Express.js-rajapinnan reittien käsittelijät hoitavat ohjaimen tehtävät (Controller) ja StudentModel-, GradeModel- ja CourseModel-moduulit vastaavat tietojen käsittelystä (Model). Näkymät sijaitsevat erillisessä Qt-asiakassovelluksessa.
flowchart TD
subgraph frontend["Qt-käyttöliittymä"]
MainWindow["MainWindow"]
Login_Qt["Login"]
StudentInfo_Qt["StudentInfo"]
MyData_Qt["MyData"]
MyGrades_Qt["MyGrades"]
EnrollToCourse_Qt["EnrollToCourse"]
MainWindow --> Login_Qt
Login_Qt --> StudentInfo_Qt
StudentInfo_Qt --> MyData_Qt
StudentInfo_Qt --> MyGrades_Qt
StudentInfo_Qt --> EnrollToCourse_Qt
end
subgraph backend["REST-rajapinta"]
RouteLogin["RouteLogin"]
RouteStudent["RouteStudent"]
RouteGrade["RouteGrade"]
RouteCourse["RouteCourse"]
Student_model["StudentModel"]
Grade_model["GradeModel"]
Course_model["CourseModel"]
DatabaseJs["database.js"]
RouteLogin --> Student_model
RouteStudent --> Student_model
RouteGrade --> Grade_model
RouteCourse --> Course_model
Student_model --> DatabaseJs
Grade_model --> DatabaseJs
Course_model --> DatabaseJs
end
subgraph mysql["MySQL-tietokanta"]
studentdb[("studentdb")]
end
Login_Qt -->|"HTTPS"| RouteLogin
MyData_Qt -->|"HTTPS"| RouteStudent
MyGrades_Qt -->|"HTTPS"| RouteGrade
EnrollToCourse_Qt -->|"HTTPS"| RouteCourse
DatabaseJs --> studentdb```mermaid
flowchart TD
subgraph frontend["Qt-käyttöliittymä"]
MainWindow["MainWindow"]
Login_Qt["Login"]
StudentInfo_Qt["StudentInfo"]
MyData_Qt["MyData"]
MyGrades_Qt["MyGrades"]
EnrollToCourse_Qt["EnrollToCourse"]
MainWindow --> Login_Qt
Login_Qt --> StudentInfo_Qt
StudentInfo_Qt --> MyData_Qt
StudentInfo_Qt --> MyGrades_Qt
StudentInfo_Qt --> EnrollToCourse_Qt
end
subgraph backend["REST-rajapinta"]
RouteLogin["RouteLogin"]
RouteStudent["RouteStudent"]
RouteGrade["RouteGrade"]
RouteCourse["RouteCourse"]
Student_model["StudentModel"]
Grade_model["GradeModel"]
Course_model["CourseModel"]
DatabaseJs["database.js"]
RouteLogin --> Student_model
RouteStudent --> Student_model
RouteGrade --> Grade_model
RouteCourse --> Course_model
Student_model --> DatabaseJs
Grade_model --> DatabaseJs
Course_model --> DatabaseJs
end
subgraph mysql["MySQL-tietokanta"]
studentdb[("studentdb")]
end
Login_Qt -->|"HTTPS"| RouteLogin
MyData_Qt -->|"HTTPS"| RouteStudent
MyGrades_Qt -->|"HTTPS"| RouteGrade
EnrollToCourse_Qt -->|"HTTPS"| RouteCourse
DatabaseJs --> studentdb
```Määrittelyvaiheessa laadittuja kaavioita ja luonnoksia voidaan joutua tarkentamaan suunnitteluvaiheessa. Määrittelyvaiheen viestiyhteyskaavio kuvaa opiskelijan ja oppilasrekisterin vuorovaikutusta yleisellä tasolla. Seuraavassa kaaviossa sama tapahtumakulku tarkentuu käyttöliittymän, rajapinnan ja tietokannan välisiksi viesteiksi. Myös käyttötapauskaavio ja käyttötapauskortti toimivat teknisen suunnittelun lähtökohtina.
Viestiyhteyskaavio näyttää kirjautumisen ja opiskelijan toimintovalinnan etenemisen käyttöliittymän, REST-rajapinnan ja tietokannan välillä. Näin määrittelyvaiheen yleistasoinen kuvaus tarkentuu tekniseksi viestinnäksi.
sequenceDiagram
actor Student as Opiskelija
participant UI as Käyttöliittymä
participant API as REST-rajapinta
participant DB as Tietokanta
Student->>UI: Syöttää tunnukset
UI->>API: Lähettää kirjautumispyynnön
API->>DB: Tarkistaa tunnukset
DB-->>API: Tarkistuksen tulos
alt Kirjautuminen onnistuu
API-->>UI: Kirjautumistunniste
UI-->>Student: Näyttää valikon
alt Henkilötietojen katselu
Student->>UI: Valitsee henkilötiedot
UI->>API: Pyytää henkilötiedot
API->>DB: Hakee henkilötiedot
DB-->>API: Henkilötiedot
API-->>UI: Henkilötiedot
UI-->>Student: Näyttää henkilötiedot
else Arvosanojen katselu
Student->>UI: Valitsee arvosanat
UI->>API: Pyytää arvosanat
API->>DB: Hakee arvosanat
DB-->>API: Arvosanat
API-->>UI: Arvosanat
UI-->>Student: Näyttää arvosanat
else Kurssille ilmoittautuminen
Student->>UI: Valitsee kurssille ilmoittautumisen
UI->>API: Pyytää ilmoittautumista
API->>DB: Tallentaa opiskelijan ilmoittautumisen kurssille
DB-->>API: Vahvistus
API-->>UI: Vahvistus
UI-->>Student: Näyttää vahvistuksen
end
else Kirjautuminen epäonnistuu
API-->>UI: Kirjautuminen epäonnistui
UI-->>Student: Näyttää kirjautumislomakkeen uudelleen
end```mermaid
sequenceDiagram
actor Student as Opiskelija
participant UI as Käyttöliittymä
participant API as REST-rajapinta
participant DB as Tietokanta
Student->>UI: Syöttää tunnukset
UI->>API: Lähettää kirjautumispyynnön
API->>DB: Tarkistaa tunnukset
DB-->>API: Tarkistuksen tulos
alt Kirjautuminen onnistuu
API-->>UI: Kirjautumistunniste
UI-->>Student: Näyttää valikon
alt Henkilötietojen katselu
Student->>UI: Valitsee henkilötiedot
UI->>API: Pyytää henkilötiedot
API->>DB: Hakee henkilötiedot
DB-->>API: Henkilötiedot
API-->>UI: Henkilötiedot
UI-->>Student: Näyttää henkilötiedot
else Arvosanojen katselu
Student->>UI: Valitsee arvosanat
UI->>API: Pyytää arvosanat
API->>DB: Hakee arvosanat
DB-->>API: Arvosanat
API-->>UI: Arvosanat
UI-->>Student: Näyttää arvosanat
else Kurssille ilmoittautuminen
Student->>UI: Valitsee kurssille ilmoittautumisen
UI->>API: Pyytää ilmoittautumista
API->>DB: Tallentaa opiskelijan ilmoittautumisen kurssille
DB-->>API: Vahvistus
API-->>UI: Vahvistus
UI-->>Student: Näyttää vahvistuksen
end
else Kirjautuminen epäonnistuu
API-->>UI: Kirjautuminen epäonnistui
UI-->>Student: Näyttää kirjautumislomakkeen uudelleen
end
```Seuraavat kaaviot kuvaavat valittuja toteutuksen osia, niiden tietoja, toimintoja ja välisiä suhteita. Ne eivät esitä sovelluksen koko rakennetta.
Edellä kuvattu MVC-mallia mukaileva työnjako näkyy reitti- ja Model-moduulien välisinä riippuvuuksina. Express-rajapinnan voi toteuttaa myös luokilla, mutta reitit ja väliohjelmistot rakennetaan usein funktioista ja moduuleista. Siksi tämä luokkakaavion merkintöjä käyttävä kuva havainnollistaa osien vastuita ja riippuvuuksia eikä vastaa yksi yhteen koodin luokkia. Esimerkiksi database.js on moduuli, joka vie connection-yhteysaltaan StudentModelin ja GradeModelin käyttöön. Qt-sovelluksen lomakkeet puolestaan on tässä mallinnettu C++-luokkina, joten niiden luokkakaavio vastaa suoremmin toteutuksen rakennetta.
classDiagram
class App {
-router: Router
+authenticateToken(request, response, next) void
+use(root) void
+use(login) void
+use(student) void
+use(grade) void
}
class RouteLogin {
-router: Router
-bcrypt: bcryptjs
-jwt: jsonwebtoken
-config: dotenv
-generateAccessToken(username) string
+POST() void
}
class RouteStudent {
-router: Router
+GET() jsonArray
+GET(username) jsonObject
+POST(jsonArray) int
+PUT(string, jsonArray) int
+DELETE(string) int
}
class RouteGrade {
-router: Router
+GET(username) jsonArray
}
class StudentModel {
-connection: Pool
-query(string) void
+getAll(callback) QueryResult
+getOne(string, callback) QueryResult
+add(jsonArray, callback) QueryResult
+update(string, jsonArray, callback) QueryResult
+delete(string, callback) QueryResult
}
class GradeModel {
-connection: Pool
+getByStudent(username, callback) QueryResult
}
class DatabaseJs["database.js (moduuli)"] {
+connection: Pool
}
App --> RouteLogin
App --> RouteStudent
App --> RouteGrade
RouteStudent --> StudentModel
RouteLogin --> StudentModel
RouteGrade --> GradeModel
StudentModel ..> DatabaseJs
GradeModel ..> DatabaseJs```mermaid
classDiagram
class App {
-router: Router
+authenticateToken(request, response, next) void
+use(root) void
+use(login) void
+use(student) void
+use(grade) void
}
class RouteLogin {
-router: Router
-bcrypt: bcryptjs
-jwt: jsonwebtoken
-config: dotenv
-generateAccessToken(username) string
+POST() void
}
class RouteStudent {
-router: Router
+GET() jsonArray
+GET(username) jsonObject
+POST(jsonArray) int
+PUT(string, jsonArray) int
+DELETE(string) int
}
class RouteGrade {
-router: Router
+GET(username) jsonArray
}
class StudentModel {
-connection: Pool
-query(string) void
+getAll(callback) QueryResult
+getOne(string, callback) QueryResult
+add(jsonArray, callback) QueryResult
+update(string, jsonArray, callback) QueryResult
+delete(string, callback) QueryResult
}
class GradeModel {
-connection: Pool
+getByStudent(username, callback) QueryResult
}
class DatabaseJs["database.js (moduuli)"] {
+connection: Pool
}
App --> RouteLogin
App --> RouteStudent
App --> RouteGrade
RouteStudent --> StudentModel
RouteLogin --> StudentModel
RouteGrade --> GradeModel
StudentModel ..> DatabaseJs
GradeModel ..> DatabaseJs
```Onnistuneen kirjautumisen jälkeen avautuu StudentInfo-lomake. Siitä opiskelija voi siirtyä MyData-lomakkeeseen katsomaan henkilötietoja, MyGrades-lomakkeeseen katsomaan kurssisuorituksia tai EnrollToCourse-lomakkeeseen ilmoittautumaan kurssille.
classDiagram
class MainWindow {
-objLogin: Login
-on_btnStart_clicked() void
}
class Login {
-postManager: QNetworkAccessManager
-reply: QNetworkReply
-response_data: QByteArray
-objStudentInfo: StudentInfo
-on_btnLogin_clicked() void
-loginSlot(reply) void
}
class StudentInfo {
-username: QString
-myToken: QByteArray
-objMyData: MyData
-objMyGrades: MyGrades
-objEnrollToCourse: EnrollToCourse
-on_btnData_clicked() void
-on_btnGrade_clicked() void
-on_btnEnroll_clicked() void
+setUsername(newUsername) void
+setMyToken(newMyToken) void
}
class MyData {
-username: QString
-myToken: QByteArray
-dataManager: QNetworkAccessManager
-reply: QNetworkReply
-response_data: QByteArray
+loadPersonalData() void
-dataSlot(reply) void
}
class MyGrades {
-username: QString
-myToken: QByteArray
-gradeManager: QNetworkAccessManager
-reply: QNetworkReply
-response_data: QByteArray
+loadGrades() void
-gradeSlot(reply) void
}
class EnrollToCourse {
-username: QString
-myToken: QByteArray
-enrollmentManager: QNetworkAccessManager
-reply: QNetworkReply
-response_data: QByteArray
+enroll(courseId) void
-enrollmentSlot(reply) void
}
MainWindow *-- Login
Login *-- StudentInfo
StudentInfo *-- MyData
StudentInfo *-- MyGrades
StudentInfo *-- EnrollToCourse```mermaid
classDiagram
class MainWindow {
-objLogin: Login
-on_btnStart_clicked() void
}
class Login {
-postManager: QNetworkAccessManager
-reply: QNetworkReply
-response_data: QByteArray
-objStudentInfo: StudentInfo
-on_btnLogin_clicked() void
-loginSlot(reply) void
}
class StudentInfo {
-username: QString
-myToken: QByteArray
-objMyData: MyData
-objMyGrades: MyGrades
-objEnrollToCourse: EnrollToCourse
-on_btnData_clicked() void
-on_btnGrade_clicked() void
-on_btnEnroll_clicked() void
+setUsername(newUsername) void
+setMyToken(newMyToken) void
}
class MyData {
-username: QString
-myToken: QByteArray
-dataManager: QNetworkAccessManager
-reply: QNetworkReply
-response_data: QByteArray
+loadPersonalData() void
-dataSlot(reply) void
}
class MyGrades {
-username: QString
-myToken: QByteArray
-gradeManager: QNetworkAccessManager
-reply: QNetworkReply
-response_data: QByteArray
+loadGrades() void
-gradeSlot(reply) void
}
class EnrollToCourse {
-username: QString
-myToken: QByteArray
-enrollmentManager: QNetworkAccessManager
-reply: QNetworkReply
-response_data: QByteArray
+enroll(courseId) void
-enrollmentSlot(reply) void
}
MainWindow *-- Login
Login *-- StudentInfo
StudentInfo *-- MyData
StudentInfo *-- MyGrades
StudentInfo *-- EnrollToCourse
```Edellisistä käyttötapauksista, käyttöliittymäluonnoksista ja kaavioista voidaan etsiä tietoja, joita sovelluksen täytyy tallentaa. Tässä esimerkissä niitä ovat:
Tietotarpeista voidaan laatia esimerkiksi seuraava yksinkertaistettu ER-malli. Se näyttää myös tietojen väliset suhteet: opiskelija voi ilmoittautua usealle kurssille, ja ilmoittautumisesta voi syntyä yksi suoritus. Taulujen tunnisteet ja muut tarkemmat kentät ovat tietokantasuunnittelussa tehtäviä valintoja.
Mermaidin ER-syntaksi vaatii suhteen selitekentän. Koodissa käytetään tyhjää selitettä, jotta kaaviossa näkyvät vain yhteydet ja niiden lukumääräsuhteet. Kaaviokohtainen asetteluasetus jättää taulujen väliin enemmän tilaa, jotta suhteen merkit erottuvat.
---
config:
layout: dagre
er:
rankSpacing: 140
---
erDiagram
STUDENT {
int student_id PK
string student_number UK
string name
string email
string password_hash
}
COURSE {
int course_id PK
string name
int credits
}
ENROLLMENT {
int enrollment_id PK
int student_id FK
int course_id FK
date enrollment_date
string status
}
COURSE_COMPLETION {
int completion_id PK
int enrollment_id FK, UK
int grade
date completion_date
}
STUDENT ||--o{ ENROLLMENT : ""
COURSE ||--o{ ENROLLMENT : ""
ENROLLMENT ||--o| COURSE_COMPLETION : ""```mermaid
---
config:
layout: dagre
er:
rankSpacing: 140
---
erDiagram
STUDENT {
int student_id PK
string student_number UK
string name
string email
string password_hash
}
COURSE {
int course_id PK
string name
int credits
}
ENROLLMENT {
int enrollment_id PK
int student_id FK
int course_id FK
date enrollment_date
string status
}
COURSE_COMPLETION {
int completion_id PK
int enrollment_id FK, UK
int grade
date completion_date
}
STUDENT ||--o{ ENROLLMENT : ""
COURSE ||--o{ ENROLLMENT : ""
ENROLLMENT ||--o| COURSE_COMPLETION : ""
```Määrittelyjä tarkennetaan työn edetessä. Jos suunnittelussa havaitaan puuttuva sääntö tai ristiriita, päivitä ensin sovittu vaatimus ja sen jälkeen siihen liittyvät kuvaukset.
Tämä sivu on opetusesimerkki eikä valmis, kattava dokumentaatio. Esimerkin tarkoitus on esitellä, kuinka Mermaidilla luodaan tyypillisiä UML-kaavioita ja muita määrittelyssä ja suunnittelussa käytettäviä kaavioita, sekä antaa vinkkejä siihen, mitä määrittely- ja suunnitteluvaiheen dokumentteihin kirjoitetaan.