Table of Contents
Johdanto
Malli-View-Controller (MVC) -malli on ollut verkkosovellusten kehittämisen kulmakivi jo vuosikymmeniä. Kun sovellukset kuitenkin kasvavat monimutkaisina ja käyttäjien kysyntä kasvaa, monet tiimit huomaavat, että niiden malleista ja liiketoimintalogiikasta vastaava taso on nopeasti tullut pullonkauloja. Huonosti rakennetut mallit johtavat tiiviiseen liitäntään, päällekkäiseen logiikkaan ja koodipohjaan, joka vastustaa muutosta. Skaalaus edellyttää tarkoituksellista, kurinalaista mallin suunnittelua. Tämä artikkeli tarjoaa kattavan joukon parhaita käytäntöjä MVC-sovellusten jäsentelyyn, jossa hyödynnetään todistettuja arkkitehtonisia malleja ja tuotantokokemusta.
MVC-kaavion ymmärtäminen
MVC-mallissa sovellus erotetaan kolmeen toisiinsa liitettyyn osaan:
- Malli:[ Hallitsee tietoja, liiketoiminnan sääntöjä ja pysyvyys logiikkaa. Se on yksi totuuden lähde sovelluksen .
- Näytä:[ Luo käyttöliittymän uudelleen tyypillisesti lukemalla mallista (tai sen esityssuuntautuneesta esityksestä).
- Ohjaaja:[ Käsittää käyttäjän syötteet, orkestroi vuorovaikutusta mallin ja näkymän välillä ja päivittää tilaa vastaavasti.
Vaikka näkymä ja ohjain ovat tärkeitä, malli on paikka, jossa suurin osa älyllisestä monimutkaisuudesta on. Hyvin jäsennelty malli mahdollistaa sovelluksen mukautumisen uusiin vaatimuksiin, lisääntyneen liikenteen käsittelemisen ja useiden rajapintojen (esim. verkko, API, mobiili) tukemisen ilman että muutoksia on tapahtunut.
Skaalattavissa olevien mallien keskeiset periaatteet
Ennen sukellus tiettyihin kuvioihin, on tärkeää sisällyttää mukaan muutamia perusperiaatteita:
- Yksi vastuu:[ Jokaisella mallilla tai luokassa pitäisi olla yksi tarkoin määritelty syy muuttaa. Esimerkiksi erillinen tietojen saatavuus liiketoiminnan validoinnista.
- Kohtausten erottaminen:[ Sovelluksen eri näkökohdat (jatkuvuus, validointi, ilmoitus jne.) olisi toteutettava erillisinä, löyhästi kytkettyinä kerroksina.
- Don...Toista itseäsi (DRY):[] Monita logiikkaa useissa malleissa tai ohjaimissa johtaa ylläpito painajaisiin. Sen sijaan, poimia yhteinen käyttäytyminen uudelleenkäytettäviin palveluihin tai ominaisuuksiin.
- Vastuu Inversio:[ Korkean tason moduulit olisi riippuvainen abstraktiot (interfaces), ei konkreettisia implementations. Tämä mahdollistaa vaihto tietokantoja, välimuistin tarjoajat, tai ulkoiset palvelut ilman kirjoittamalla liiketoiminnan logiikkaa.
Verkkoalueen ja Driven-suunnittelu (DDD)
Eric Evans.Domain-Driven Design on edelleen yksi tehokkaimmista tavoista mallin skaalautuvuuteen. DDD kannustaa kehittäjiä järjestämään malleja ydinliiketoiminta-alueiden ympärille eikä teknisiin kysymyksiin.
Kieli
Luo yhteinen sanasto, jota kehittäjät, verkkoalueen asiantuntijat ja sidosryhmät jakavat. Käytä samoja termejä koodissa, dokumentaatiossa ja keskusteluissa. Esimerkiksi sähköisen kaupankäynnin sovelluksessa pitäisi olla luokka, joka heijastaa tosimaailman järjestystä, ei yleistä .
Rajatut kontekstit
Suuria sovelluksia on useita ala-alueita. DDD suosittelee selkeiden rajojen määrittämistä kontekstien välillä.Esimerkiksi erilliset mallit tilausten hallintaan, varastoon ja merenkulkuun. Jokaisessa rajatussa kontekstissa mallit voidaan optimoida kyseiselle alueelle ilman, että niistä vuotaa konsepteja rajojen yli. Eristyminen on avain skaalautumiseen kehitystiimien itsenäisesti.
Aggregaatit
Yhdistetty on ryppää verkkotunnuskohteita käsitellään yhtenä yksikkönä. Root-yhteisö takaa johdonmukaisuuden. Esimerkiksi -aggregaatti voisi sisältää ja -yhteisöjä, jotka kaikki ovat käytettävissä tilaus juuri. Tämä kuvio vähentää monimutkaisia suhteita ja yksinkertaistaa liiketoimia.
Syvempää sukellusta varten ks. Martin Fowler...
Layered Architecture
Laakeroitu arkkitehtuuri erottaa huolet edelleen organisoimalla mallin eri loogisiksi tasoiksi:
- Domain Layer:[ Sisältää liiketoimintayksiköt, arvo esineitä, ja verkkotunnuspalvelut. Tämä kerros ei ole riippuvaisia infrastruktuurista.
- Application Layer:[ Orkesterit käyttävät tapauksia, koordinoivat verkkotunnus objekteja ja hallinnoi tapahtumia. Se riippuu verkkotunnuskerros.
- Infrastruktuuritaso:[ Toteuttaa pysyvyyttä, viestit, ulkoiset API-puhelut ja muut tekniset huolenaiheet. Se riippuu verkkotunnuksen ja sovelluskerroksista.
- Esitystaso:[] Ohjaimet ja näkemykset, jotka ovat vuorovaikutuksessa sovelluskerroksen kanssa rajapintojen kautta.
Tämä erottelu varmistaa, että muutokset tietokantatekniikkaan, välimuististrategiaan tai käyttöliittymän kehykseen eivät murenna liiketoiminnan ydinlogiikkaa. Se myös helpottaa yksikön testausta.
Muut palvelut
Mallien puhtaanapitämiseen ja skaalautumiseen tarvitaan kaksi mallia:
Versiovaraston kuvio
Arkistossa on datan käyttölogiikka, joka tarjoaa verkkotunnusobjektien in-muistin kokoelman kaltaisen käyttöliittymän. Sen sijaan, että sirottelisit tietokantakyselyitä kauttaaltaan, soitat . Tämä abstraktio mahdollistaa datalähteen vaihdon (esim. MySQL:stä PostgreSQL:ään tai jopa muistin sisäiseen testaukseen) mahdollisimman vähäisellä vaikutuksella.
Palvelutaso
Palvelut sisältävät liiketoimintalogiikkaa, joka ei luonnollisesti kuulu yhteen yksikköön. Esimerkiksi voi koordinoida validointia, hinnoittelua ja varastotarkastuksia tilauksen yhteydessä. Palvelut riippuvat arkistoista ja verkkoalueyksiköistä, mutta pysyvät agnostikkoina tietokannassa. Tämä erottelu helpottaa myös uudelleenkäyttöä eri valvojien, taustatyön ja sovellusliittymän välillä.
Tiedonsiirto-objektit (DTOs) ja Näytä mallit
Koko verkkotunnuksen mallin paljastaminen näköalatasolle tai ulkoisille API-asiakkaille luo tiiviin kytkennän ja usein paljastaa tarpeettomia sisäisiä yksityiskohtia. Sen sijaan käytä DTO-työkaluja muokkaamaan tietoja juuri niin kuin tarvitset. Edut ovat:
- Poikkeus:[ Verkkotunnusyksiköiden muutokset eivät automaattisesti riko API-asiakkaita.
- Turvallisuus:[ Arkaluontoiset kentät (esim. sisäiset tunnisteet, tarkastusaikaleimat) voidaan jättää pois.
- Suorituskyky:[ DTO voidaan räätälöidä siten, että siihen sisältyvät vain tietyn päätepisteen edellyttämät kentät, jolloin hyötykuorman koko pienenee.
Näytä mallit palvelevat samaa tarkoitusta esitystaso, joka sisältää vain tiedot, jotka näkymä tarvitsee tehdä (usein rinnalla näyttö logiikka, kuten formatoitu päivämääriä tai laskennallisia kokonaismääriä).
Optimoidaan tietokannan käyttömahdollisuudet skalabilitylle
Jopa puhtain malliarkkitehtuuri epäonnistuu, jos tietokanta on tehoton.
Indeksi
Analysoidaan kyselymalleja ja luodaan indeksit sarakkeissa [, ja []. Yliindeksit voivat hidastaa kirjoittamista, joten mittaa ja seuraa.
Kyselyvälimuisti
Käytä muistin myymälöissä kuten Redis tai Memcached välimuistin tuloksia kalliita kyselyitä. Toteuta välimuistin mitätöinti sopiva verkkotunnuksen (aikapohjainen, tapahtuma-ohjautunut, tai manuaalinen).
Pegination ja laiska Ladataan
Älä koskaan lataa suuria tiedostoja muistiin. Käytä kursoripohjaista tai offset-pagiinaatiota. ORM-laitteissa voit laiskuutta lapsisuhteissa, mutta varo N+1-kyselyongelmia tarvittaessa, käytä innokasta lastausta (esim. ActiveRecord- tai SQL-muodossa.
Laiska ladataan vs. Eager Ladataan
Oikean kuormausstrategian valinta on suorituskyvyn kannalta ratkaisevan tärkeää:
- Laiska Ladataan:[ Vastaavat tiedot ladataan vain, kun niitä on saatavilla. Tämä on tehokas yhden yksikön toiminnoissa, mutta se voi heikentää suorituskykyä silmukoissa (pelossa N+1 ongelma).
- Eager Ladataan:[ Lataa kaikki tarvittavat suhteet etukäteen yhdessä kyselyssä. Käytä, kun tiedät, että näkymä tai palvelu tarvitsee siihen liittyviä tietoja. Monet ORM-ohjelmat tukevat eksplisiittistä innokasta lastausta tai ennusteita.
Käytännöllinen lähestymistapa on oletus innokas lataaminen tunnettuja polkuja ja käyttää laiska lastaus vain harvoin käy yhdistysten. Profiloida tietokanta kyselyt alle realistinen kuorma löytää oikea tasapaino.
Horisontaalisen mittakaavan suunnittelu
Kun sovelluksesi kasvaa yhden palvelimen ulkopuolelle, mallikerroksen on tuettava jakelua:
- Stateless Mallit:[ Vältä käyttäjäistunto- tai pyyntökohtaisten tietojen tallentamista mallitilanteissa. Käytä riippuvuusruisketta tarjotaksesi kansalaisuudettomia palveluja.
- Toimiva serialisointi:[ Mallit, jotka kulkevat verkon poikki (esim. JSON API:n kautta) olisi suunniteltava nopeaan serialisointiin/deerialisointiin. Käytä DTO-malleja eikä monimutkaisia objektigraafioita, joissa on pyöreät viitetiedot.
- Tietokannan jakaminen:[ Erittäin suurten tietokantojen osalta data jaetaan useisiin tietokantoihin. Arkistokerrostasi tulisi abstraktisti käyttää sirpalointilogiikkaa, ihanteellisesti reititysstrategialla, joka perustuu kokooma juuriin.
- Tapahtumakohtainen johdonmukaisuus:[ Jaetuissa järjestelmissä vältetään hajautettuja liiketoimia, jotka lukitsevat resursseja eri palveluihin. Sen sijaan ne kattavat mahdollisen johdonmukaisuuden tapahtumalähtöisten mallien, kuten tapahtumien ja viestijonojen avulla.
Parhaiden käytäntöjen lisääminen
Riippuvuus injektiosta
Käytä riippuvuusruiskutusastiaa ratkaisemaan säilytysvaraston ja huoltoriippuvuudet. Tämä decouples mallintaa rakenteen konkreettisista toteutuksista ja tekee siitä turhan vaihtaa osia testaukseen tai skaalaukseen.
Muuttumattomuus
Aina kun mahdollista, designarvoesineitä voidaan muuttaa. Mutatoitumaton luokka vähentää salanimeen ja koncurrentaatioon liittyviä vikoja. Lisäksi muuttumattomat mallit ovat helpompi testata ja välimuisti.
Testaus eristyksen yhteydessä
Yksikkötestit palveluille ja verkkotunnuksen logiikka ei pitäisi vaatia tietokantaa tai puite-käynnistysjälkeä. Käytä made-arkistoja tai muistinsisäisiä toteutuksia. Integrointitestit voivat todentaa pysyvyyden suhteessa todelliseen tietokantaan, mutta pitävät ne kohdennettujna.
Korruptiontorjuntataso
Kun integroidaan perinteisiin järjestelmiin tai ulkoisiin sovellusliittymiin, rakennetaan korruption vastainen kerros, joka kääntää mallin ja ulkoisen järjestelmän mallin välille. Tämä estää ulkopuolisten muutosten vuotamisen verkkotunnukseesi.
Dokumentointi ja koodien tarkastelu
Mallirakenteet muuttuvat usein läpinäkymättömiksi ajan mittaan. Säilytä arkkitehtuurin päätöksentekoa koskevat tiedot (ADR) ja varmista johdonmukaisuus koodin tarkastelun avulla. Hyvin dokumentoitu malli maksaa osinkoja, kun se saapuu uusille tiimin jäsenille tai kun moduulia tarkistetaan kuukausia myöhemmin.
Päätelmät
Skaalausmallit MVC-mallissa eivät ole kertaluonteisia suunnitteluharjoituksia vaan jatkuvaa kurinalaisuutta. Noudattamalla periaatteita, kuten huolet eriyttämistä, DDD:n ja kerrostetun arkkitehtuurin soveltamista sekä viisaasti käyttämällä arkistoja, palveluita ja DTO:itä, luot mallikerroksen, joka voi kasvaa sovelluksellasi. Optimoimalla datan saatavuutta, valitsemalla oikean latauksen strategian ja suunnittelemalla horisontaalista skaalautumista varmistat, että sovelluksesi pysyy kuormitettuna. Muista, että jokainen arkkitehtoninen päätös sisältää kompromissit.
Jatkotutkimusta varten harkitse opiskelua [Evans.Domain-Driven Design book ja Redis välimuistin kuviot[. Nämä resurssit antavat syvemmän käsityksen täällä käsitellyistä kuvioista.