Kun kävin iltakoulua tullakseni ohjelmoijaksi, opin useita suunnittelumalleja: singleton, repository, factory, builder, decorator jne. Suunnittelumallit antavat meille hyväksi todetun ratkaisun olemassa oleviin ja toistuviin ongelmiin. En oppinut, että samanlainen mekanismi on olemassa korkeammalla tasolla: ohjelmistoarkkitehtuurikuviot. Nämä ovat sovelluksen tai sovellusten yleistä ulkoasua koskevia malleja. Niillä kaikilla on etuja ja haittoja. Ja ne kaikki puuttuvat tiettyihin ongelmiin.

Kerrosmalli

Kerrosmalli on luultavasti yksi tunnetuimmista ohjelmistoarkkitehtuurimalleista. Monet kehittäjät käyttävät sitä tietämättä sen nimeä. Ideana on jakaa koodi ”kerroksiin”, joissa jokaisella kerroksella on tietty vastuu ja se tarjoaa palvelua ylemmälle kerrokselle.

Kerroksia ei ole ennalta määriteltyä määrää, mutta näitä näet useimmiten:

  • Esitys- tai käyttöliittymäkerros
  • Sovelluskerros
  • Liiketoiminta- tai toimialuekerros
  • Persistenssi- tai tiedonsaantikerros
  • Tietokantakerros

Ajatuksena on, että käyttäjä käynnistää esityskerroksessa sijaitsevan koodin suorittaessaan jonkun toiminnon (esim.esim. painikkeen napsauttaminen). Tämän jälkeen esityskerros kutsuu taustalla olevaa kerrosta eli sovelluskerrosta. Sitten siirrytään liiketoimintakerrokseen ja lopuksi pysyvyyskerros tallentaa kaiken tietokantaan. Ylemmät kerrokset ovat siis riippuvaisia alemmista kerroksista ja tekevät kutsuja alemmille kerroksille.

Sovellusten monimutkaisuudesta riippuen näet variaatioita tästä. Jotkin sovellukset saattavat jättää sovelluskerroksen pois, kun taas toiset lisäävät välimuistikerroksen. On jopa mahdollista yhdistää kaksi kerrosta yhdeksi. Esimerkiksi ActiveRecord-malli yhdistää liiketoiminta- ja pysyvyyskerroksen.

Kerroksen vastuu

Kuten mainittiin, jokaisella kerroksella on oma vastuunsa. Esityskerros sisältää sovelluksen graafisen suunnittelun sekä kaiken käyttäjän vuorovaikutusta käsittelevän koodin. Tähän kerrokseen ei pidä lisätä logiikkaa, joka ei liity nimenomaan käyttöliittymään.

Liiketoimintakerrokseen sijoitetaan mallit ja logiikka, jotka liittyvät nimenomaan liiketoimintaongelmaan, jota yrität ratkaista.

Sovelluskerros sijaitsee esityskerroksen ja liiketoimintakerroksen välissä. Toisaalta se tarjoaa abstraktion, jotta esityskerroksen ei tarvitse tuntea liiketoimintakerrosta. Teoriassa voit vaihtaa esityskerroksen teknologiapinoa muuttamatta mitään muuta sovelluksessa (esim. vaihtaa WinFormsista WPF:ään). Toisaalta sovelluskerros tarjoaa paikan, jonne voidaan sijoittaa tietty koordinointilogiikka, joka ei sovi liiketoiminta- tai esityskerrokseen.

Loppujen lopuksi pysyvyyskerros sisältää koodin, jolla tietokantakerrosta käytetään. Tietokantakerros on taustalla oleva tietokantatekniikka (esim. SQL Server, MongoDB). Pysyvyyskerros on tietokannan käsittelyyn tarkoitettu koodikokonaisuus: SQL-lauseet, yhteyden yksityiskohdat jne.

Hyötyjä

  • Tämä malli on useimmille kehittäjille tuttu.
  • Se tarjoaa helpon tavan kirjoittaa hyvin organisoitu ja testattava sovellus.

Haitat

  • Se johtaa yleensä monoliittisiin sovelluksiin, joita on vaikea pilkkoa jälkikäteen.
  • Kehittäjät huomaavat usein kirjoittavansa paljon koodia eri kerrosten läpikäymiseksi ilman, että näillä kerroksilla on mitään lisäarvoa. Jos kirjoitat vain yksinkertaisen CRUD-sovelluksen, kerroksittainen malli saattaa olla sinulle liikaa.

Ideaalinen

  • Tyypillisille line-of-business-sovelluksille, jotka tekevät muutakin kuin pelkkiä CRUD-operaatioita

Mikroydin

Mikroydin-kuvio eli plug-in-kuvio on käyttökelpoinen silloin, kun sovelluksellasi on ydinkohtaiset vastuualueet ja niiden rinnalla kokoelma vaihdettavia osia. Mikroydin tarjoaa sisäänmenopisteen ja sovelluksen yleisen kulun ilman, että oikeastaan tiedetään, mitä eri lisäosat tekevät.

Esimerkkinä on tehtäväsuunnittelija. Mikroydin voisi sisältää kaiken logiikan tehtävien aikatauluttamista ja käynnistämistä varten, kun taas lisäosat sisältävät tiettyjä tehtäviä. Kunhan lisäosat noudattavat ennalta määriteltyä API:ta, mikroydin voi käynnistää ne ilman, että sen tarvitsee tietää toteutuksen yksityiskohtia.

Toinen esimerkki on työnkulku. Työnkulun toteutus sisältää käsitteitä, kuten eri vaiheiden järjestys, vaiheiden tulosten arviointi, seuraavan vaiheen päättäminen jne. Vaiheiden konkreettinen toteutus on vähemmän tärkeää työnkulun ydinkoodin kannalta.

Hyötyjä

  • Tämä malli tarjoaa suurta joustavuutta ja laajennettavuutta.
  • Joidenkin toteutusten avulla voidaan lisätä lisäosia sovelluksen ollessa käynnissä.
  • Mikroydintä ja lisäosia voivat kehittää erilliset tiimit.

Haitat

  • Voi olla vaikea päättää, mikä kuuluu mikroytimeen ja mikä ei.
  • Ennalta määritetty API ei ehkä sovi hyvin tuleville lisäosille.

Edullinen

  • Sovelluksille, jotka ottavat dataa eri lähteistä, muuntavat sitä ja kirjoittavat sen eri kohteisiin
  • Työnkulkusovelluksille
  • Tehtävä- ja työnsuunnittelusovelluksille

CQRS

CQRS on lyhenne sanoista Command and Query Responsibility Segregation (komento- ja kyselyvastuun erottelu). Tämän mallin keskeinen käsite on, että sovelluksessa on lukuoperaatioita ja kirjoitusoperaatioita, jotka on erotettava toisistaan täysin. Tämä tarkoittaa myös sitä, että kirjoitusoperaatioihin (komennot) käytettävä malli eroaa lukumalleista (kyselyt). Lisäksi tiedot tallennetaan eri paikkoihin. Relaatiotietokannassa tämä tarkoittaa, että komentomallia varten on tauluja ja lukumallia varten tauluja. Jotkin toteutukset jopa tallentavat eri mallit täysin eri tietokantoihin, esimerkiksi SQL Server komentomallille ja MongoDB lukumallille.

Tämä malli yhdistetään usein tapahtumahankintaan, jota käsittelemme jäljempänä.

Miten se tarkalleen ottaen toimii? Kun käyttäjä suorittaa toiminnon, sovellus lähettää komennon komentopalveluun. Komentopalvelu hakee tarvitsemansa tiedot komentotietokannasta, tekee tarvittavat käsittelyt ja tallentaa ne takaisin tietokantaan. Sitten se ilmoittaa asiasta lukupalvelulle, jotta lukumalli voidaan päivittää. Tämä virtaus näkyy alla.

Kun sovelluksen on näytettävä tietoja käyttäjälle, se voi hakea lukumallin kutsumalla lukupalvelua, kuten alla näkyy.

Edut

  • Käskymalleissa voidaan keskittyä liiketoimintalogiikkaan ja validointiin, kun taas lukumallit voidaan räätälöidä tiettyihin skenaarioihin.
  • Välttää monimutkaisia kyselyjä (esim. Joins SQL:ssä), mikä tekee lukemisesta suorituskykyisempää.

Haitat

  • Komento- ja lukumallien synkronoinnin ylläpitäminen voi olla monimutkaista.

Edullinen

  • Sovelluksiin, jotka odottavat suuria lukumääriä
  • Sovelluksiin, joissa on monimutkaisia toimialueita

Tapahtumahankinta

Kuten edellä mainitsin, CQRS kulkee usein käsi kädessä tapahtumahankinnan kanssa. Tämä on malli, jossa tietokantaan ei tallenneta mallin nykytilaa, vaan mallille tapahtuneet tapahtumat. Kun asiakkaan nimi muuttuu, arvoa ei siis tallenneta ”Nimi”-sarakkeeseen. Tallennat ”NameChanged”-tapahtuman, jossa on uusi arvo (ja mahdollisesti myös vanha arvo).

Kun haluat hakea mallin, haet kaikki sen tallennetut tapahtumat ja sovellat ne uudelleen uuteen objektiin. Kutsumme tätä objektin uudelleenkytkennäksi.

Todellisessa elämässä tapahtumahankinnan analogia on kirjanpito. Kun lisäät menon, et muuta loppusumman arvoa. Kirjanpidossa lisätään uusi rivi suoritettavalla operaatiolla. Jos tehtiin virhe, lisätään vain uusi rivi. Jotta elämäsi olisi helpompaa, voisit laskea loppusumman aina, kun lisäät rivin. Tätä summaa voidaan pitää lukumallina. Alla olevan esimerkin pitäisi tehdä asia selvemmäksi.

Voit nähdä, että teimme virheen, kun lisäsimme laskun 201805. Sen sijaan, että olisimme muuttaneet riviä, lisäsimme kaksi uutta riviä: ensin yhden väärän rivin peruuttamiseksi ja sitten uuden ja oikean rivin. Näin tapahtumahankinta toimii. Tapahtumia ei koskaan poisteta, koska ne ovat kiistatta tapahtuneet menneisyydessä. Tilanteiden korjaamiseksi lisäämme uusia tapahtumia.

Huomaa myös, miten meillä on solu, jossa on kokonaisarvo. Tämä on yksinkertaisesti kaikkien edellä olevien solujen arvojen summa. Excelissä se päivittyy automaattisesti, joten voisi sanoa, että se synkronoituu muiden solujen kanssa. Se on lukumalli, joka tarjoaa helpon näkymän käyttäjälle.

Tapahtumahankinta yhdistetään usein CQRS:ään, koska objektin uudelleenkytkentä voi vaikuttaa suorituskykyyn, varsinkin jos instanssille on paljon tapahtumia. Nopea lukumalli voi parantaa sovelluksen vasteaikaa merkittävästi.

Hyötyjä

  • Tämä ohjelmistoarkkitehtuurimalli voi tarjota tarkastuslokin valmiiksi. Jokainen tapahtuma edustaa datan manipulointia tiettynä ajankohtana.

Haitat

  • Se vaatii tiettyä kurinalaisuutta, koska vääriä tietoja ei voi korjata pelkällä muokkauksella tietokannassa.
  • Tapahtuman rakenteen muuttaminen ei ole triviaali tehtävä. Jos esimerkiksi lisäät ominaisuuden, tietokannassa on edelleen tapahtumia ilman tätä tietoa. Koodisi on käsiteltävä tätä puuttuvaa tietoa armollisesti.

Edullinen sovelluksille, jotka

  • Haluavat julkaista tapahtumia ulkoisiin järjestelmiin
  • Tulee rakentaa CQRS:llä
  • Joilla on monimutkaisia toimialueita
  • Tarvitsevat tarkastuslokin tietojen muutoksista

Mikropalvelut

Kun kirjoitat sovelluksen joukoksi mikropalveluja, kirjoitat itse asiassa useita sovelluksia, jotka toimivat yhdessä. Jokaisella mikropalvelulla on oma erillinen vastuualueensa, ja tiimit voivat kehittää niitä muista mikropalveluista riippumatta. Ainoa riippuvuus niiden välillä on viestintä. Kun mikropalvelut kommunikoivat keskenään, sinun on varmistettava, että niiden välillä lähetettävät viestit pysyvät taaksepäin yhteensopivina. Tämä vaatii jonkin verran koordinointia, varsinkin jos eri tiimit vastaavat eri mikropalveluista.

Kaavio voi selittää.

Yllä olevassa kaaviossa sovellus kutsuu keskitettyä API:ta, joka välittää kutsun oikeaan mikropalveluun. Tässä esimerkissä on erilliset palvelut käyttäjäprofiilille, varastolle, tilauksille ja maksulle. Voit kuvitella, että kyseessä on sovellus, jossa käyttäjä voi tilata jotain. Erilliset mikropalvelut voivat myös kutsua toisiaan. Maksupalvelu voi esimerkiksi ilmoittaa tilaukset-palvelulle, kun maksu onnistuu. Tilaukset-palvelu voisi sitten kutsua varastopalvelua säätämään varastoa.

Ei ole olemassa selkeää sääntöä siitä, kuinka suuri mikropalvelu voi olla. Edellisessä esimerkissä käyttäjäprofiilipalvelu voi vastata tiedoista, kuten käyttäjän käyttäjätunnuksesta ja salasanasta, mutta myös kotiosoitteesta, avatar-kuvasta, suosikeista jne. Vaihtoehtona voisi olla myös kaikkien näiden vastuualueiden jakaminen vielä pienempiin mikropalveluihin.

Hyötyjä

  • Voit kirjoittaa, ylläpitää ja ottaa käyttöön jokaisen mikropalvelun erikseen.
  • Mikropalveluarkkitehtuurin pitäisi olla helpompi skaalautua, koska voit skaalautua vain niihin mikropalveluihin, jotka on skaalattava. Sovelluksen harvemmin käytettyjä osia ei tarvitse skaalata.
  • Sovelluksen osia on helpompi kirjoittaa uudelleen, koska ne ovat pienempiä ja vähemmän kytköksissä muihin osiin.

Haitat

  • Hyötyjä
    • Vastoin odotuksia on itse asiassa helpompaa kirjoittaa aluksi hyvin jäsennelty monoliittinen kokonaisuus (monolithi), joka voidaan jakaa mikropalveluihin myöhemmin. Mikropalveluissa on paljon ylimääräisiä huolenaiheita: kommunikointi, koordinointi, taaksepäin yhteensopivuus, kirjaaminen jne. Tiimeillä, joilla ei ole tarvittavaa taitoa kirjoittaa hyvin jäsenneltyä monoliittia, on luultavasti vaikeuksia kirjoittaa hyviä mikropalveluja.
    • Käyttäjän yksi toiminto voi kulkea usean mikropalvelun läpi. Vikaantumispisteitä on enemmän, ja kun jokin menee pieleen, ongelman paikantaminen voi viedä enemmän aikaa.

    Edal for:

    • Sovellukset, joissa tiettyjä osia käytetään intensiivisesti ja jotka on skaalattava
    • Palvelut, jotka tarjoavat toiminnallisuutta useille muille sovelluksille
    • Sovellukset, jotka muuttuisivat hyvin monimutkaisiksi, jos ne yhdistettäisiin yhdeksi monoliitiksi
    • Sovellukset, joissa voidaan määritellä selkeitä rajattuja konteksteja

    Kombinoida

    Olen selittänyt jo useampia ohjelmistojen arkkitehtuurimalleja, sekä niiden edut ja haitat. Mutta on olemassa muitakin malleja kuin ne, jotka olen tässä esittänyt. Ei ole myöskään harvinaista yhdistää useita näistä malleista. Ne eivät aina sulje toisiaan pois. Sinulla voi esimerkiksi olla useita mikropalveluja, ja jotkut niistä voivat käyttää kerroksittaista mallia, kun taas toiset käyttävät CQRS:ää ja tapahtumahankintaa.

    Tärkeää on muistaa, että ei ole olemassa yhtä ratkaisua, joka toimii kaikkialla. Kun kysymme, mitä mallia kannattaa käyttää sovelluksessa, ikivanha vastaus pätee edelleen: ”se riippuu”. Kannattaa punnita ratkaisun hyvät ja huonot puolet ja tehdä tietoon perustuva päätös.

Vastaa

Sähköpostiosoitettasi ei julkaista.