Mallit aloittelijoille: MVC vs MVP vs MVVM. Yleiset säännöt mallin valinnassa. Valikoima hyödyllisiä linkkejä aiheesta

Ohjaimet

Rekisterinpitäjä käsittelee jokaisen hakemukseen saapuvan pyynnön. Rekisterinpitäjä voi käsitellä pyynnön mielivaltaisella tavalla, kunhan se ei ylitä mallin ja näkymän vastuurajaa. Tämä tarkoittaa, että ohjaimet eivät saa sisältää tai tallentaa tietoja, eivätkä ne saa luoda käyttöliittymiä.

ASP.NET MVC Frameworkissa ohjaimet ovat .NET-luokkia, jotka sisältävät pyynnön käsittelyyn tarvittavan logiikan. Ohjaimen tehtävänä on kapseloida sovelluslogiikka. Toisin sanoen ohjaimet ovat vastuussa saapuvien pyyntöjen käsittelystä ja toimintojen suorittamisesta mallille aihealue ja käyttäjälle hahmonnettavien näkymien valitseminen.

Esimerkkisovellus

Tätä varten ja seuraavat artikkelit me luomme uusi projekti MVC nimesi ControllersAndActionsiksi käyttämällä Tyhjennä-mallia valitsemalla MVC-valintaruudun Lisää kansioita ja ydinviittauksia -osiossa ja yksikkötestiprojektissa nimeltä ControllersAndActions.Tests. Luomasi yksikkötestit eivät vaadi valetoteutuksia, joten sinun ei tarvitse asentaa Moq-pakettia, mutta sinun on asennettava MVC-paketti, jotta testit pääsevät käsiksi taustalla oleviin ohjainluokkiin.

Kirjoita Visual Studio NuGet Package Manager Console -ikkunaan seuraava komento:

Asennuspaketti Microsoft.Aspnet.Mvc -versio 5.0.0 -projektin nimi ControllersAndActions.Tests

Valitse projektin luomisen jälkeen Visual Studio -ympäristön Projekti (Projekti) -valikosta ControllersAndActions Properties (Properties ControllersAndActions), avautuvassa valintaikkunassa siirry välilehdelle Web (Web) ja valitse valintanappi Specific Page ( Tietty sivu) Aloita toiminta -luokassa. Sinun ei tarvitse syöttää mitään arvoa - valitse vain valintanappi.

Ohjaimen käsite

Olet nähnyt ohjaimen käyttötapauksia melkein jokaisessa aiemmassa ASP.NET MVC -artikkelissa. On aika katsoa kulissien taakse.

Ohjaimen luominen IController-liittymän avulla

MVC Frameworkissa ohjainluokkien on toteutettava IController-liitäntä nimiavaruudesta System.Web.Mvc näkyy alla olevassa esimerkissä:

System.Web.Routingin käyttö; nimiavaruus System.Web.Mvc ( julkinen käyttöliittymä IController ( void Execute(RequestContext requestContext); ) )

Saadaksesi tämän käyttöliittymän määritelmän, sinun on ladattava MVC Frameworkin lähdekoodi, joka on erittäin hyödyllinen kehystyökalujen sisäisen toiminnan ymmärtämiseksi.

Kuten näet, IController-käyttöliittymä on hyvin yksinkertainen. Hänen ainoa Execute()-menetelmä kutsutaan, kun tälle ohjainluokalle tehdään pyyntö. MVC Framework selvittää, mihin luokkaan pyyntö kohdistuu lukemalla reititystietojen generoiman ohjainominaisuuden arvon tai käyttämällä erityisiä reititysluokkia.

Voit luoda ohjainluokkia toteuttamalla IController-käyttöliittymän, mutta koska tämä käyttöliittymä on matalatasoinen, sinun on tehtävä paljon työtä saadaksesi jotain hyödyllistä. IController-käyttöliittymä on kuitenkin hyödyllinen ohjaimien toiminnan esittelyssä, ja tätä tarkoitusta varten luodaan Ohjaimet-kansioon uusi luokkatiedosto nimeltä BasicController.cs, jonka sisältö näkyy alla olevassa esimerkissä:

System.Web.Mvc; käyttämällä System.Web.Routingia; nimitila ControllersAndActions.Controllers ( julkinen luokka BasicController: IController ( public void Execute(RequestContext requestContext)) ( merkkijonoohjain = (merkkijono)requestContext.RouteData.Values["ohjain"]; merkkijono toiminta = (merkkijono)requestContext.Route"action.Values "]; requestContext.HttpContext.Response.Write(string.Format("Ohjain: (0), Toimintomenetelmä: (1)", ohjain, toiminto)); ) ) )

IController-liitännän Execute()-menetelmälle välitetään RequestContext-objekti, joka tarjoaa tietoja nykyisestä pyynnöstä ja sitä vastaavasta reitistä (ja saa ohjaimen kutsumaan käsittelemään pyyntöä). RequestContext-luokka määrittää kaksi ominaisuutta, jotka on kuvattu alla olevassa taulukossa:

HttpContextBase-objekti tarjoaa pääsyn joukkoon objekteja, jotka kuvaavat nykyistä pyyntöä, joita kutsutaan kontekstiobjekteiksi. palaamme niihin myöhemmin. RouteData-objekti kuvaa reittiä. RouteData-luokan tärkeät ominaisuudet on lueteltu alla olevassa taulukossa:

Artikkelissa Reititysjärjestelmän määrittäminen osoitti, kuinka voit käyttää RouteBase- ja IRouteHandler-tyyppejä reititysjärjestelmän määrittämiseen. Tässä esimerkissä Arvot-ominaisuuden avulla saadaan ohjaimen ja toimintasegmenttien muuttujien arvot, jotka sitten kirjoitetaan vastaukseen.

Osa mukautettujen ohjaimien luomisen ongelmasta on pääsyn puute ominaisuuksiin, kuten näkymiin. Tämä tarkoittaa, että sinun on työskenneltävä alemmalla tasolla, minkä vuoksi sisällön kirjoittaminen suoraan vastauksena asiakkaalle. Omaisuus HttpContextBase.Response palauttaa HttpResponseBase-objektin, jonka avulla voit määrittää ja lisätä sisältöä asiakkaalle lähetettävään vastaukseen. Tämä on toinen yhteyspiste ASP.NET:n ja MVC Frameworkin välillä.

Jos suoritat sovelluksen ja siirryt URL-osoitteeseen, kuten /Basic/Index, erityinen ohjain luo alla olevassa kuvassa näkyvän tulosteen:

IController-rajapinnan toteutuksen avulla voit luoda luokan, jonka MVC Framework tunnistaa ohjaimeksi ja lähettää sille pyyntöjä ilman rajoituksia pyynnön käsittelylle ja sille generoidulle vastaukselle. Tämä hyvä esimerkki, koska se osoittaa, kuinka laajennettavissa MVC Framework voi olla jopa keskeisille rakennuspalikoille, kuten ohjaimille, mutta kirjoittamiselle monimutkainen sovellus tällä tavalla voi olla huomattavia vaikeuksia.

Luokat, joiden nimet päättyvät Base

MVC Framework luottaa ASP.NET:iin pyyntöjen käsittelyssä, mikä on järkevää, koska tämä alusta on todistettu ja monipuolinen toteutus, joka integroituu tiiviisti IIS-sovelluspalvelimeen. Ongelmana on, että ASP.NETin käyttämät luokat antamaan tietoja pyynnöistä eivät sovellu yksikkötestaukseen, mikä on MVC-kehyksen käytön tärkein etu.

Microsoft päätti ottaa käyttöön testattavuuden säilyttäen samalla yhteensopivuuden olemassa olevia sovelluksia ASP.NET Web Forms, joten tulos on Perusluokat. Nämä luokat on nimetty näin, koska niillä on samat nimet kuin tärkeimmillä ASP.NET-alustan luokilla, joita seuraa sana Base.

Esimerkiksi ASP.NET tarjoaa kontekstuaalisia tietoja nykyisestä pyynnöstä ja useista tärkeistä sovelluspalveluista HttpContext-objektin kautta. Sitä vastaava perusluokka on HttpContextBase, jonka ilmentymä välitetään IController-rajapinnassa määritellylle Execute()-metodille (muut Base-luokat esitellään myöhemmissä esimerkeissä). Alkuperäiset luokat ja perusluokat määrittävät samat ominaisuudet ja menetelmät, mutta perusluokat aina abstraktia, mikä tarkoittaa, että niitä on helppo käyttää yksikkötestaukseen.

Joskus päädyt jonkin alkuperäisen ASP.NET-luokan esiintymään, kuten HttpContext. Tällaisessa tapauksessa on tarpeen luoda MVC-ystävällinen perusluokka, joka on samanlainen kuin HttpContextBase. Tämä tehdään käyttämällä yhtä seuraavista Käärimiskurssit, joilla on samat nimet kuin alkuperäisillä luokilla, täydennettynä sanalla Wrapper, kuten HttpContextWrapper . Wrapper-luokat on johdettu perusluokista, ja niissä on konstruktorit, jotka ottavat esiintymiä alkuperäisistä luokista:

Alkuluokat, perusluokat ja Wrapper-luokat määritellään System.Web-nimiavaruudessa, joten ASP.NET voi tukea sujuvasti MVC Frameworkia ja vanhempia sovelluksia. verkkosovelluksia lomakkeita.

Ohjaimen luominen perimällä ohjainluokalta

Kuten edellisessä esimerkissä osoitettiin, MVC Framework mahdollistaa lähes rajattoman mukauttamisen ja laajentamisen. Voit toteuttaa IController-liittymän tarjoamaan minkä tahansa haluamasi pyyntöjen käsittelyn ja tulosten luonnin. Etkö pidä toimintatavoista? Etkö halua huolehtia renderoiduista näkymistä? Siinä tapauksessa voit ottaa asiat omiin käsiisi ja toteuttaa paremman, nopeamman ja tyylikkäämmän tavan käsitellä pyyntöjä. Vaihtoehtoisesti voit hyödyntää Microsoft MVC Framework -tiimin tarjoamia työkaluja ja johtaa ohjaimesi System.Web.Mvc.Controller-luokasta.

Controller-luokka tarjoaa pyyntöjen käsittelytuen, joka on tuttu useimmille MVC-sovelluskehittäjille. Sitä käytettiin kaikissa aiemmissa artikkeleissa käsitellyissä esimerkeissä. Controller-luokka tarjoaa kolme keskeiset rahastot jotka on kuvattu alla:

Toimintatavat

Ohjaimen käyttäytyminen on hajautettu moniin menetelmiin (sen sijaan, että se toteutettaisiin muodossa ainoa menetelmä Suorittaa()). Jokainen toimintomenetelmä liittyy vastaavaan URL-osoitteeseen ja sitä kutsutaan saapuvasta pyynnöstä haettujen parametrien avulla.

Toimien tulokset

Voit palauttaa objektin, joka kuvaa toiminnon tulosta (kuten näkymän renderöinnin tai uudelleenohjauksen toiseen URL-osoitteeseen tai toimintomenetelmään), ja käsitellä sen sitten haluamallasi tavalla. Tulosten määrittelyn ja niiden suorittamisen erottaminen toisistaan ​​yksinkertaistaa yksikkötestausta.

Suodattimet

Uudelleen käytettävä toiminta (kuten todennus) voidaan kapseloida suodattimiksi ja merkitä sitten ohjaimien ja toimintatapojen toiminnan jokainen osa lähdekoodin attribuutilla.

Ellet ole tekemisissä tietyn vaatimuksen kanssa, paras tapa luoda ohjaimia on periä ne Controller-luokasta, minkä, kuten voit odottaa, Visual Studio tekee luodessaan uusi luokka vastauksena valikkokohdan Lisää --> Scaffold (Lisää --> Malli) valitsemiseen.

Alla oleva esimerkki on koodi yksinkertainen ohjain nimeltä DerivedController luotu samalla tavalla. Se luotiin käyttämällä MVC 5 Controller - Empty -versiota, jossa on useita yksinkertaisia ​​muutoksia, joka on suunniteltu asettamaan ViewBag-ominaisuus ja valitsemaan näkymä:

Järjestelmän käyttö; käyttäen System.Web; käyttämällä System.Web.Mvc:tä; nimitila ControllersAndActions.Controllers ( julkinen luokka DerivedController: Controller ( julkinen ActionResult Index() ( ViewBag.Message = "Hei ohjaimelta DerivedController -toimintomenetelmäindeksi"; return View("MyView"); ) ) )

Controller-luokka tarjoaa myös linkin Razor-näkymäjärjestelmään. Tässä esimerkissä palautetaan View()-metodin kutsuminen, joka ottaa parametriksi asiakkaalle hahmonnettavan näkymän nimen. Luo tämä näkymä luomalla Views/Dived-kansio ja napsauta sitä oikealla painikkeella hiirellä ja valitse kontekstivalikko item Lisää --> MVC 5 Näytä sivu (Partaveitsi) (Lisää --> MVC 5 Näytä sivu (Razor)). Nimeä se MyView.cshtml ja luo näkymätiedosto napsauttamalla OK.

Muuta tiedoston sisältö esimerkkiä vastaavaksi:

@(ViewBag.Title = "Hakemisto"; } MyView Сообщение от контроллера: « @ViewBag.Message »!}

Kun sovellus on käynnistetty ja navigoitu URL-osoitteeseen, kuten /Dived/Index, tätä toimintomenetelmää kutsutaan ja MyView hahmonnetaan:

Controller-luokasta periminen johtaa tarpeeseen toteuttaa toimintatapoja, vastaanottaa kaikki pyynnön käsittelemiseen tarvittavat syötteet ja luoda sopiva vastaus. Seuraavissa artikkeleissa kuvataan monia tapoja tehdä tämä.

Monet ihmiset alkavat kirjoittaa projektia työskennelläkseen yhden tehtävän kanssa, eivätkä tarkoita, että siitä voi kasvaa monen käyttäjän hallintajärjestelmä, sanotaanko sisältö tai, varjelkoon, tuotanto. Ja kaikki näyttää olevan hienoa ja siistiä, kaikki toimii kunnes alat ymmärtää, että kirjoitettu koodi koostuu kokonaan kainalosauvoista ja hardcodesta. Koodi on sekoitettu asettelua, pyyntöjä ja kainalosauvoja, joskus jopa lukukelvoton. Esiin tulee kiireellinen ongelma: kun lisäät uusia ominaisuuksia, joudut viuhtelemaan tämän koodin kanssa hyvin pitkään, muistaen "mitä siellä oli kirjoitettu?" ja kiroa itseäsi menneisyydessä.

Olet ehkä jopa kuullut suunnittelukuvioista ja jopa selannut näitä upeita kirjoja:

  • E. Gamma, R. Helm, R. Johnson, J. Vlissidess "Esiön tekniikat suuntautunut muotoilu. Suunnittelumalleja";
  • M. Fowler "Yritysohjelmistosovellusten arkkitehtuuri".
Ja monet, jotka eivät pelänneet valtavia käsikirjoja ja dokumentaatiota, yrittivät tutkia mitä tahansa nykyaikaista kehystä ja kohdatessaan ymmärtämisvaikeuksia (johtuen monista arkkitehtonisista käsitteistä, jotka on taitavasti yhdistetty toisiinsa), lykkäävät niiden tutkimista ja soveltamista. nykyaikaiset työkalut takapolttimessa.

Esitetty artikkeli on hyödyllinen ensisijaisesti aloittelijoille. Joka tapauksessa toivon, että saat muutaman tunnin sisällä käsityksen MVC-toteutukset malli, joka on kaikkien nykyaikaisten verkkokehysten taustalla, ja hanki "ruokaa" lisäpohdintaa varten "miten se tehdään". Artikkelin lopussa on valikoima hyödyllisiä linkkejä, joka auttaa myös ymmärtämään, mistä verkkokehykset (MVC:n lisäksi) koostuvat ja miten ne toimivat.

Kovettuneet PHP-ohjelmoijat eivät todennäköisesti löydä tästä artikkelista mitään uutta itselleen, mutta heidän kommenteistaan ​​ja kommenteistaan ​​päätekstiin olisi paljon apua! Koska ilman teoriaa käytäntö on mahdotonta, ja ilman käytäntöä teoria on hyödytöntä, sitten aluksi on vähän teoriaa ja sitten siirrytään käytäntöön. Jos olet jo perehtynyt MVC:n käsitteeseen, voit ohittaa teoriaosan ja hypätä suoraan käytäntöön.

1. Teoria MVC-malli kuvaa yksinkertaista tapaa rakentaa sovellusrakenne, jonka tarkoituksena on erottaa liiketoimintalogiikka käyttöliittymästä. Tämän seurauksena sovellus on helpompi skaalata, testata, ylläpitää ja tietysti toteuttaa.

Harkitse MVC-mallin käsitteellistä järjestelmää (mielestäni tämä on menestynein kaavio niistä, joita olen nähnyt):

Arkkitehtuurissa MVC malli tarjoaa tiedot ja liiketoimintalogiikan säännöt, näkymä vastaa käyttöliittymästä ja ohjain tarjoaa mallin ja näkymän välisen vuorovaikutuksen.

Tyypillinen MVC-sovelluksen työnkulku voidaan kuvata seuraavasti:

  • Kun käyttäjä syöttää verkkoresurssiin, alustuskomentosarja luo sovelluksen esiintymän ja käynnistää sen suoritettavaksi.
    Tämä näyttää esimerkiksi näkymän kotisivu sivusto.
  • Sovellus vastaanottaa pyynnön käyttäjältä ja määrittää pyydetyn ohjaimen ja toiminnon. Pääsivun tapauksessa suoritetaan oletustoiminto ( indeksi).
  • Sovellus instantoi ohjaimen ja suorittaa toimintamenetelmän,
    joka sisältää esimerkiksi kutsuja mallille, jotka lukevat tietoa tietokannasta.
  • Tämän jälkeen toiminto luo näkymän mallista saaduista tiedoista ja näyttää tuloksen käyttäjälle.
  • Malli - sisältää sovelluksen liiketoimintalogiikan ja sisältää menetelmiä näytteenottoa varten (nämä voivat olla ORM-menetelmiä), prosessointia (esim. validointisäännöt) ja tiettyjen tietojen antamista, mikä usein tekee siitä erittäin paksua, mikä on aivan normaalia.
    Mallin ei pitäisi olla suoraan vuorovaikutuksessa käyttäjän kanssa. Kaikki käyttäjän pyyntöön liittyvät muuttujat tulee käsitellä ohjaimessa.
    Malli ei saa luoda HTML-koodia tai muuta renderöintikoodia, joka voi muuttua käyttäjän tarpeiden mukaan. Tällaista koodia tulisi käsitellä näkymissä.
    Sama malli esimerkiksi: käyttäjätunnistusmallia voidaan käyttää sekä sovelluksen käyttäjä- että hallintaosassa. Siinä tapauksessa voit ottaa yhteinen koodi erilliseen luokkaan ja periä siitä, määrittämällä perillisille ominaisia ​​alisovelluksia koskevia menetelmiä.

    Näytä - käytetään asettamaan ohjaimesta ja mallista vastaanotettujen tietojen ulkoinen näyttö.
    Näkymät sisältävät HTML-merkintöjä ja pieniä PHP-koodin lisäyksiä tietojen indeksointia, muotoilua ja näyttämistä varten.
    Ei pitäisi päästä suoraan tietokantaan. Mallien pitäisi tehdä tämä.
    Ei pitäisi toimia käyttäjän pyynnöstä saatujen tietojen kanssa. Tämä tehtävä on suoritettava ohjaimen toimesta.
    Se voi päästä suoraan ohjaimen tai mallien ominaisuuksiin ja menetelmiin saadakseen lähtövalmiita tietoja.
    Näkymät on yleensä jaettu yhteiseen mallipohjaan, joka sisältää kaikille sivuille yhteiset merkinnät (esimerkiksi ylä- ja alatunnisteen) ja malliosiin, joita käytetään mallin tietojen näyttämiseen tai tietojen syöttölomakkeiden näyttämiseen.

    Ohjain on linkki, joka yhdistää mallit, näkymät ja muut komponentit sisään toimiva sovellus. Rekisterinpitäjä vastaa käyttäjien pyyntöjen käsittelystä. Ohjain ei saa sisältää SQL-kyselyjä. On parempi säilyttää ne malleissa. Ohjain ei saa sisältää HTML-koodia tai muita merkintöjä. Se ansaitsee tuoda esiin.
    Hyvin suunnitellussa MVC-sovelluksessa ohjaimet ovat yleensä hyvin ohuita ja sisältävät vain muutaman kymmenen rivin koodia. Mitä ei voida sanoa Stupid Fat Controllerista (SFC) CMS Joomlassa. Ohjaimen logiikka on melko tyypillistä ja suurin osa siitä on otettu ulos perusluokat.
    Mallit sen sijaan ovat erittäin paksuja ja sisältävät suurimman osan tietojenkäsittelyyn liittyvästä koodista. datan rakenne ja sen sisältämä liiketoimintalogiikka ovat yleensä varsin erityisiä tietylle sovellukselle.

    1.1. Front Controller ja Page Controller Useimmissa tapauksissa käyttäjän vuorovaikutus verkkosovelluksen kanssa tapahtuu linkkien kautta. Katso nyt selaimen osoitepalkkia - sait tämän tekstin tästä linkistä. Muut linkit, kuten tämän sivun oikealla puolella olevat linkit, ohjaavat sinut muuhun sisältöön. Siten linkki edustaa tiettyä komentoa verkkosovellukseen.

    Toivottavasti olet jo huomannut, että eri sivustoilla voi olla täydellinen eri formaatteja rakennus osoitekenttä. Jokainen muoto voi edustaa verkkosovelluksen arkkitehtuuria. Vaikka näin ei aina ole, se on useimmissa tapauksissa selvä tosiasia.

    Harkitse osoitepalkin kahta vaihtoehtoa, jotka näyttävät tekstiä ja käyttäjäprofiilin.

    Likimääräinen käsittelykoodi tässä tapauksessa:
    switch($_GET["action"]) ( case "about" : request_once("about.php"); // "Tietoja meistä" -sivunvaihto; tapaus "contacts" : request_once("contacts.php"); // sivu "Yhteystiedot" tauko; kirjainkoko "feedback" : request_once("feedback.php"); // sivu "Feedback" tauko; oletus: request_once("page404.php"); // sivu "404" tauko; )
    Luulen, että melkein kaikki ovat tehneet tämän aiemmin.

    URL-reititysmoottorin avulla voit määrittää sovelluksesi hyväksymään tällaiset pyynnöt näyttämään samat tiedot:
    http://www.example.com/contacts/feedback

    Tässä yhteystiedot on ohjain ja palaute on yhteystietojen ohjaimen menetelmä, joka tekee lomakkeen palautetta jne. Palaamme tähän asiaan käytännön osassa.

    On myös syytä tietää, että monien verkkokehysten reitittimet antavat sinun luoda mielivaltaisia URL-reitit(ilmoita, mitä kukin URL-osoitteen osa tarkoittaa) ja niiden käsittelysäännöt.
    Nyt meillä on tarpeeksi teoreettista tietoa, jotta voimme siirtyä käytäntöön.

    2. Harjoittele ensin, luodaan seuraavaa rakennetta tiedostot ja kansiot:


    Tulevaisuudessa sanon, että perusluokat Model, View ja Controller tallennetaan ydinkansioon.
    Heidän lapsensa tallennetaan ohjaimien, mallien ja näkymien hakemistoihin. Index.php-tiedosto on sovelluksen sisääntulokohta. Bootstrap.php-tiedosto käynnistää sovelluksen latauksen, mukaan lukien kaikki tarvittavat moduulit jne.

    Mennään peräkkäin; avaa index.php-tiedosto ja täytä se seuraavalla koodilla:
    ini_set("näyttö_virheet", 1); request_once "application/bootstrap.php";
    Tässä ei pitäisi olla kysymyksiä.

    Siirrytään seuraavaksi suoraan bootstrap.php-tiedostoon:
    request_once "core/model.php"; request_once "core/view.php"; request_once "core/controller.php"; request_once "core/route.php"; Reitti::aloitus(); // käynnistä reititin
    Kolme ensimmäistä riviä sisältävät tällä hetkellä olemattomia ydintiedostoja. Viimeiset rivit sisällytä tiedosto reititinluokkaan ja suorita se suorittamista varten soittamalla staattinen menetelmä alkaa.

    2.1. URL-reitittimen käyttöönotto Toistaiseksi poiketaan MVC-mallin toteutuksesta ja keskitytään reitittämiseen. Ensimmäinen askel, joka meidän on tehtävä, on laittaa seuraava koodi .htaccess-tiedostoon:
    RewriteEngine On RewriteCond %(REQUEST_FILENAME) !-f RewriteCond %(REQUEST_FILENAME) !-d RewriteRule .* index.php [L]
    Tämä koodi ohjaa kaikkien sivujen käsittelyn osoitteeseen index.php , jota tarvitsemme. Muistatko, että ensimmäisessä osassa puhuimme etuohjaimesta?!

    Sijoitamme reitityksen erilliseen route.php-tiedostoon ydinhakemistoon. Tässä tiedostossa kuvataan Route-luokka, joka ajaa ohjaimien metodit, jotka puolestaan ​​luovat sivujen ulkoasun.

    Route.php-tiedoston sisältö

    class Route ( staattinen funktio start() ( // oletusohjain ja toiminto $controller_name = "Main"; $toiminnan_nimi = "indeksi"; $routes = explode("/", $_SERVER["REQUEST_URI"]); // get ohjaimen nimi if (!empty($routes)) ( $ohjaimen_nimi = $reitit; ) // hanki toiminnon nimi if (!empty($routes)) ( $toiminnan_nimi = $reitit; ) // lisää etuliitteitä $mallin_nimi = " Malli_ ".$controller_name; $controller_name = "Controller_".$controller_name; $action_name = "action_".$action_name; // kiinnitä tiedosto malliluokkaan (mallitiedostoa ei ehkä ole) $mallitiedosto = strtolower($mallin_nimi ). ".php"; $mallin_polku = "sovellus/mallit/".$mallitiedosto; if(tiedosto_olemassa($malli_polku)) (sisältää "sovellus/mallit/".$mallitiedosto; ) // kiinnitä ohjainluokkatiedosto $controller_file = strtolower ($ohjaimen_nimi).".php"; $ohjaimen_polku = "sovellus/ohjaimet/".$ohjain_tiedosto; if(tiedosto_olemassa($ohjaimen_polku)) (sisältää "sovellus/ohjaimet/".$ohjain_tiedosto; ) else ( /* tähän olisi oikein heittää poikkeus, mutta yksinkertaisuuden vuoksi ohjaamme välittömästi 404-sivulle */ Route::ErrorPage404(); ) // luo ohjaimen $controller = new $ohjaimen_nimi; $toiminto = $toiminnan_nimi; if(method_exists($controller, $action)) ( // kutsua ohjaintoimintoa $controller->$action(); ) else ( // olisi myös järkevämpää heittää poikkeus tähän Route::ErrorPage404(); ) ) function ErrorPage404( ) ( $host = "http://".$_SERVER["HTTP_HOST"]."/"; header("HTTP/1.1 404 Ei löydy"); header("Tila: 404 Ei löydy" ); header(" Sijainti:".$isäntä."404"); ) )


    Huomaan, että luokka toteuttaa hyvin yksinkertaistettua logiikkaa (huolimatta suuresta koodista) ja ehkä jopa turvallisuusongelmia. Tämä tehtiin tarkoituksella, koska. täysimittaisen reititysluokan kirjoittaminen ansaitsee ainakin erillisen artikkelin. Katsotaanpa pääkohtia...

    Globaali taulukkoelementti $_SERVER["REQUEST_URI"] sisältää koko osoite joita käyttäjä on käyttänyt.
    Esimerkiksi: example.ru/contacts/feedback

    Toiminnon käyttäminen räjähtää osoite on jaettu osiin. Tuloksena saamme ohjaimen nimen, annetussa esimerkissä tämä on ohjain yhteystiedot ja toiminnon nimi, meidän tapauksessamme - palautetta.

    Seuraavaksi yhdistetään mallitiedosto (malli saattaa puuttua) ja ohjaintiedosto, jos sellainen on, ja lopuksi luodaan ohjaininstanssi ja toiminto kutsutaan uudelleen, jos se on kuvattu ohjainluokassa.

    Joten kun menet esimerkiksi osoitteeseen:
    esimerkki.fi/portfolio
    tai
    esimerkki.fi/portfolio/indeksi
    Reititin tekee seuraavaa:

  • yhdistä Model_Portfolio.php-tiedosto mallikansiosta, joka sisältää Model_Portfolio-luokan;
  • sisällytä controller_portfolio.php-tiedosto controllers-kansiosta, joka sisältää Controller_Portfolio-luokan;
  • luo Controller_Portfolio-luokan esiintymän ja kutsuu oletustoiminnon - siinä kuvatun action_indexin.
  • Jos käyttäjä yrittää käyttää olemattoman ohjaimen osoitetta, esimerkiksi:
    example.com/ufo
    sitten se ohjataan 404-sivulle:
    esimerkki.fi/404
    Sama tapahtuu, jos käyttäjä käyttää toimintoa, jota ei ole kuvattu ohjaimessa.2.2. Paluu MVC-toteutukseen. Siirrytään ydinkansioon ja lisätään route.php-tiedostoon kolme muuta tiedostoa: model.php, view.php ja controller.php


    Muistutan, että ne sisältävät perusluokkia, joita aletaan nyt kirjoittaa.

    Model.php-tiedoston sisältö
    luokan malli ( julkinen funktio get_data() ( ) )
    Malliluokka sisältää yhden tyhjän tiedonhakumenetelmän, joka ohitetaan jälkeläisluokissa. Kun luomme jälkeläisluokkia, kaikki tulee selvemmäksi.

    View.php-tiedoston sisältö
    class View ( //public $template_view; // tässä voit määrittää julkisen oletusnäkymän. function generate($content_view, $template_view, $data = null) ( /* if(is_array($data)) ( // convert array elementit muuttujiksi Pura($data); ) */ sisältävät "application/views/".$template_view; ) )
    Ei ole vaikea arvata, että menetelmä Tuottaa suunniteltu muodostamaan näkymä. Seuraavat parametrit välitetään sille:

  • $content_file - näkymät näyttävät sivun sisällön;
  • $template_file - yhteinen malli kaikille sivuille;
  • $data on taulukko, joka sisältää sivun sisältöelementit. Yleensä täytetty malli.
  • Sisällytä-toiminto yhdistää dynaamisesti yhteisen mallipohjan (näkymän), jonka sisään näkymä upotetaan
    näyttääksesi tietyn sivun sisällön.

    Meidän tapauksessamme yleinen malli sisältää otsikon, valikon, sivupalkin ja alatunnisteen ja sivujen sisältö erilliseen muotoon. Jälleen tämä on tehty yksinkertaisuuden vuoksi.

    Controller.php-tiedoston sisältö
    luokan ohjain ( julkinen $malli; julkinen $näkymä; toiminto __construct() ( $this->view = new View(); ) function action_index() ( ) )
    Menetelmä action_index on oletusarvoisesti kutsuttu toiminto, ohitamme sen, kun toteutamme jälkeläisiä luokkia.

    2.3. Model- ja Controller-jälkeläisluokkien toteuttaminen, View'n luominen Nyt hauskuus alkaa! Käyntikorttisivustomme koostuu seuraavista sivuista:
  • Koti
  • Palvelut
  • Portfolio
  • Yhteystiedot
  • Ja myös - sivu "404"
  • Jokaisella sivulla on oma ohjain Controllers-kansiosta ja näkymä Views-kansiosta. Joillakin sivuilla voidaan käyttää mallia tai malleja mallit-kansiosta.


    Edellisessä kuvassa template_view.php-tiedosto on korostettu erikseen - tämä on malli, joka sisältää kaikille sivuille yhteisen merkinnän. Yksinkertaisimmassa tapauksessa se voisi näyttää tältä:
    Koti
    Antaaksemme sivustolle edustavan ulkoasun luomme CSS-mallin ja integroimme sen sivustoomme muuttamalla HTML-merkintöjen rakennetta ja CSS-yhteydet ja JavaScript-tiedostot:

    Artikkelin lopussa "Tulos"-osiossa on linkki GitHub-tietovarastoon, jossa on projekti, jossa yksinkertaisen mallin integrointi on tehty.

    2.3.1. Pääsivun luominen Aloitetaan ohjaimesta controller_main.php , tässä on sen koodi:
    luokka Controller_Main laajentaa ohjaimen (funktio action_index() ( $this->view->generate("main_view.php", "template_view.php"); ) )
    Menetelmä Tuottaa View-luokan esiintymä, yleisen mallipohjan tiedostojen nimet ja näkymä sivun sisällöllä välitetään.
    Indeksitoiminnon lisäksi ohjain voi tietysti sisältää muita toimintoja.

    Tiedosto osoitteesta yleisnäkymä arvioimme aiemmin. Harkitse sisältötiedostoa main_view.php:
    Tervetuloa!

    OLOLOSHA TEAM on ykkösluokan verkkosivustokehityksen asiantuntijoiden tiimi, jolla on monen vuoden kokemus meksikolaisten naamioiden, pronssi- ja kivipatsaiden keräämisestä Intiasta ja Ceylonista, bareljeefeista ja veistosista, jotka Päiväntasaajan Afrikan mestarit ovat luoneet viisi tai kuusi vuosisataa sitten. .


    Tämä sisältää yksinkertaisen merkinnän ilman PHP-kutsuja.
    Voit näyttää pääsivun käyttämällä jotakin seuraavista osoitteista:

    Esimerkki mallista saatua dataa näyttävän näkymän käytöstä käsitellään myöhemmin.

    2.3.2. Portfolio-sivun luominen Meidän tapauksessamme Portfolio-sivu on ainoa sivu, joka käyttää mallia.
    Malli sisältää yleensä tiedonhakumenetelmiä, esimerkiksi:
  • alkuperäisten pgsql- tai mysql-kirjastojen menetelmät;
  • kirjastojen menetelmät, jotka toteuttavat tiedon abstraktion. Esimerkiksi PEAR MDB2 -kirjaston menetelmät;
  • ORM-menetelmät;
  • menetelmät työskennellä NoSQL:n kanssa;
  • jne.
  • Yksinkertaisuuden vuoksi emme käytä tässä SQL-kyselyitä tai ORM-käskyjä. Sen sijaan simuloimme todellista dataa ja palautamme välittömästi joukon tuloksia.
    Model_portfolio.php-mallitiedosto sijoitetaan mallit-kansioon. Tässä sen sisältö:
    class Model_Portfolio laajentaa mallia ( julkinen funktio get_data() ( return array(array("Year" => "2012", "Site" => "http://DunkelBeer.ru", "Description" => "Dark Dunkel olut alkaen saksalainen valmistaja Löwenbraü, jonka Venäjällä valmistaa panimoyhtiö "SUN InBev"."), array("Year" => "2012", "Site" => "http://ZopoMobile.ru", "Description" => "Venäjänkielinen luettelo kiinalaiset puhelimet Zopo päälle Android pohjainen Käyttöjärjestelmä ja lisävarusteet."), // todo); ) )

    Mallin ohjainluokka sisältyy controller_portfolio.php-tiedostoon, tässä on sen koodi:
    luokka Controller_Portfolio laajentaa Controller (funktio __construct() ( $this-> model = new Model_Portfolio(); $this->view = new View(); ) toiminto action_index() ( $data = $this->model->get_data( ); $this->view->generate("portfolio_view.php", "template_view.php", $data); ) )
    muuttujaksi tiedot menetelmän palauttama taulukko kirjoitetaan get_data, jota mietimme aiemmin.
    Tämä muuttuja välitetään sitten menetelmäparametrina. Tuottaa, joka myös välitetään: yhteisen mallipohjan sisältävän tiedoston nimi ja sivun sisällön näkymän sisältävän tiedoston nimi.

    Sivun sisällön sisältävä näkymä sijaitsee portfolio_view.php-tiedostossa.
    Portfolio

    Kaikki seuraavan taulukon projektit ovat fiktiivisiä, joten älä edes yritä seurata annettuja linkkejä.
    vuosiProjektiKuvaus


    Täällä kaikki on yksinkertaista, näkymä näyttää mallista saadut tiedot.

    2.3.3. Muiden sivujen luominen Loput sivut luodaan samalla tavalla. Heidän koodinsa on saatavilla GitHubin arkistossa, jonka linkki on artikkelin lopussa, "Tulos"-osiossa.3. Tulos Ja tässä tulos:

    Kuvakaappaus tuloksena olevasta käyntikorttisivustosta



    Linkki GitHubiin: https://github.com/vitalyswipe/tinymvc/zipball/v0.1

    Mutta tässä versiossa luonnostelin seuraavat luokat (ja niitä vastaavat tyypit):

    • Controller_Login, jossa luodaan näkymä sisäänkirjautumislomakkeella ja salasanan syöttämistä varten, jonka jälkeen suoritetaan todennus ja onnistuessaan käyttäjä ohjataan hallintapaneeliin.
    • Contorller_Admin indeksitoiminnolla, joka tarkistaa, onko käyttäjä aiemmin valtuutettu sivustolle järjestelmänvalvojaksi (jos on, järjestelmänvalvojan näkymä näytetään) ja uloskirjautumistoiminnolla uloskirjautumista varten.
    Todennus ja valtuutus on eri aihe, joten sitä ei käsitellä tässä, mutta vain yllä oleva linkki annetaan aloittaaksesi.4. Johtopäätös MVC-mallia käytetään arkkitehtonisena perustana monissa kehyksissä ja sisällönhallintajärjestelmissä, jotka on luotu kehittymään paremmin monimutkaisia ​​päätöksiä lisää Lyhytaikainen. Tämän mahdollisti lisäämällä abstraktiotasoa, koska ihmisaivojen toimivien rakenteiden monimutkaisuus on rajallinen.

    Mutta useista sadoista tiedostoista koostuvien web-kehysten, kuten Yii tai Kohana, käyttäminen yksinkertaisia ​​verkkosovelluksia (esimerkiksi käyntikorttisivustoja) kehitettäessä ei ole aina suositeltavaa. Nyt voimme luoda kauniin MVC-mallin, jotta emme sekoita Php-, HTML-, CSS- ja JavaScript-koodia yhdessä tiedostossa.

    Tämä artikkeli on enemmän lähtökohta CMF:n oppimiselle kuin esimerkki jostain todella oikeasta, jonka voit ottaa verkkosovelluksesi perustana. Ehkä se jopa inspiroi sinua ja harkitset jo oman mikrokehyksen tai MVC-pohjaisen sisällönhallintajärjestelmän kirjoittamista. Mutta ennen kuin keksit seuraavan pyörän "blackjackin ja huorien" kanssa, mieti uudestaan, ehkä olisi viisaampaa suunnata voimanne olemassa olevan projektin kehittämiseen ja yhteisöön auttamiseksi?!

    P.S.: Artikkeli on kirjoitettu uudelleen ottaen huomioon jotkut kommentteihin jätetyt kommentit. Kritiikasta on ollut paljon apua. Päätellen vastauksesta: kommenteista, henkilökohtaisista vetoomuksista ja julkaisun suosikkeihinsa lisänneiden käyttäjien määrästä, idea kirjoittaa tämä viesti ei osoittautunut niin pahaksi. Valitettavasti ei ole mahdollista ottaa huomioon kaikkia toiveita ja kirjoittaa enemmän ja yksityiskohtaisemmin ajan puutteen vuoksi ... mutta ehkä ne salaperäiset persoonallisuudet, jotka miinus alkuperäinen versio tekevät tämän. Onnea projekteillesi!

    5. Valikoima hyödyllisiä linkkejä aiheesta Artikkeli käsittelee hyvin usein verkkokehysten aihetta - tämä on erittäin laaja aihe, koska jopa mikrokehykset koostuvat monista komponenteista, jotka on taitavasti linkitetty toisiinsa ja se vaatisi enemmän kuin yhden artikkelissa puhutaan näistä komponenteista. Päätin kuitenkin antaa tänne pienen valikoiman linkkejä (joihin kävin tätä artikkelia kirjoittaessani), jotka tavalla tai toisella liittyvät puitteiden aiheeseen.

    Tunnisteet: Lisää tunnisteita

    Model-View-Controller (MVC) -kuvio, joka löydettiin 1970-luvun lopulla, on arkkitehtuurin suunnittelumalli. ohjelmisto, joiden päätehtävänä on erottaa datan kanssa työskentelyn toiminnot niiden esittämisestä. Teoriassa hyvin suunniteltu MVC-sovellus mahdollistaa sen, että etu- ja taustakehittäjät eivät työn aikana puutu toistensa vastuualueisiin, eli etupään kehittäjän ei tarvitse tietää mitään "keittiöstä" hänen taustakollegansa ja päinvastoin.

    Vaikka MVC oli alun perin suunniteltu työpöytäsovellusten kehittämiseen, se on mukautettu nykyaikaiset tehtävät ja on erittäin suosittu web-kehittäjien keskuudessa, koska vastuunjaon ansiosta on mahdollista luoda selkeämpi, käyttövalmis uudelleenkäyttö koodi. MVC-malli johtaa selkeisiin, modulaarisiin järjestelmiin, joiden avulla kehittäjät voivat tehdä muutoksia olemassa olevaan koodiin hyvin nopeasti.

    Tässä artikkelissa tarkastelemme perusperiaatteet MVC, alkaen kuvion määrittelystä ja jatkaen sen soveltamista pienessä esimerkissä. Tämä artikkeli on ensisijaisesti hyödyllinen niille, jotka eivät ole koskaan kohdanneet tätä mallia elämässään, ja ehkä myös niille, jotka haluavat päivittää tietämystään MVC:stä.

    MVC:n ymmärtäminen

    Kuten jo mainittiin, kuvion nimi tulee kolmen sanan lyhenteestä: Malli (malli), View (View) ja Controller (ohjain). Lyhyesti, kuvion periaatetta voidaan havainnollistaa yhdellä kaaviolla (löytyy Wikipediasta):

    Tämä kaavio näyttää selkeästi kuvion yksisuuntaisen tiedonkulun ja kuvaa myös kunkin komponentin roolit.

    Malli

    Mallia käytetään tietojen käsittelyyn ja käsittelyyn. Useimmissa tapauksissa mallia käytetään tietovarastoon (kuten tietokantaan) pääsyyn. Malli tarjoaa käyttöliittymän tietojen hakemiseen, luomiseen, muokkaamiseen ja poistamiseen varastosta. MVC-mallin yhteydessä malli on välittäjä näkymän ja ohjaimen välillä.

    Mallin äärimmäisen tärkeä ominaisuus on, että se ei teknisesti tiedä, mitä ohjaimessa ja näkymässä oleville tiedoille tapahtuu. Mallin ei tulisi koskaan tehdä tai odottaa pyyntöjä kaavan muille osille/muilta komponenteilta.

    Muista kuitenkin aina, että malli ei ole vain pääsyyhdyskäytävä tietokantaan tai muuhun järjestelmään, jossa on kyse tietojen välittämisestä edestakaisin. Malli on kuin portti tietoihin. Malli on usein järjestelmän monimutkaisin osa, osittain siksi, että malli itsessään on linkki kaikkiin muihin osiin.

    Esitys

    Näkymä on se, jossa mallista saadut tiedot näytetään haluttu muoto. Perinteisissä MVC-mallilla kehitetyissä web-sovelluksissa näkymä on se järjestelmän osa, jossa HTML-koodi luodaan. Näkymä vastaa myös toimien vastaanottamisesta käyttäjältä lähettääkseen ne ohjaimelle. Esimerkiksi näkymä näyttää painikkeen käyttöliittymä, ja sen painamisen jälkeen se aiheuttaa vastaavan ohjaintoiminnon.

    Näkymän tarkoituksesta on joitain väärinkäsityksiä, etenkin verkkokehittäjien keskuudessa, jotka ovat vasta alkamassa rakentaa sovelluksiaan MVC:n avulla. Yksi yleisimmin rikotuista säännöistä on se, että näkymä ei saa kommunikoida mallin kanssa millään tavalla ja että kaikki näkymän vastaanottamat tiedot tulevat vain ohjaimelta. Käytännössä kehittäjät jättävät usein huomiotta tämän käsitteen, joka on MVC-mallin ydin. Fabio Cevascon artikkeli havainnollistaa tätä hämmentävää lähestymistapaa MVC:hen CakePHP:n kanssa, joka on yksi monista epästandardeista MVC-kehyksistä:

    On erittäin tärkeää ymmärtää, että oikean MVC-arkkitehtuurin saamiseksi näkymien ja mallien välillä ei pitäisi olla suoria vuorovaikutuksia. Kaikki niiden välisen tiedonvaihdon logiikka on toteutettava ohjaimissa.

    Lisäksi on yleinen väärinkäsitys, että näkymä on vain mallitiedosto. Kuten Tom Butler huomautti, tällä väärinkäsityksellä on valtava ulottuvuus, koska monet kehittäjät ymmärtävät MVC-rakenteen väärin alusta alkaen, minkä jälkeen aloittelevien kehittäjien massat alkavat syöttää tätä "tietoa" edelleen. Todellisuudessa näkymä on paljon enemmän kuin pelkkä malli, mutta monet MVC-kuvioon perustuvat puitteet ovat vääntäneet näkymän käsitteen niin paljon, että kukaan ei välitä siitä, kuinka oikeita heidän sovelluksensa ovat MVC-mallin näkökulmasta.

    Toinen tärkeä seikka on, että näkymä ei koskaan toimi "puhtaalla" ohjaimen datalla, eli ohjain ei koskaan toimi näkymän kanssa, ohittaen mallin. Ohjaimen ja näkymän välisessä vuorovaikutuksessa mallin tulee aina olla niiden välissä.

    Ohjain

    Ohjain on MVC-paketin viimeinen osa. Ohjaimen tehtävänä on vastaanottaa tietoja käyttäjältä ja manipuloida mallia. Se on ohjain, ja vain hän, se osa järjestelmää, joka on vuorovaikutuksessa käyttäjän kanssa.

    Pähkinänkuoressa ohjain voidaan kuvata tiedon kerääjäksi, joka välittää sen mallille käsittelyä ja tallennusta varten. Hänen ei pitäisi tehdä tiedoille mitään, vaan hän saa vain vastaanottaa ne käyttäjältä. Ohjain liittyy yhteen näkymään ja yhteen malliin, mikä järjestää yksisuuntaisen tietovirran, ohjaten sitä jokaisessa vaiheessa.

    On erittäin tärkeää muistaa, että ohjain aloittaa toimintansa vasta käyttäjän vuorovaikutuksen seurauksena näkymän kanssa, joka kutsuu vastaavaa ohjaintoimintoa. Yleisin virhe kehittäjien keskuudessa on, että ohjainta pidetään yksinkertaisesti yhdyskäytävänä näkymän ja mallin välillä. Seurauksena on, että ohjaimella on ne toiminnot, jotka näkymän tulisi suorittaa (muuten, tästä tulee ajatus, että näkymä on vain mallitiedosto). Tämän lisäksi monet yleensä tyhjentävät kaiken tietojenkäsittelyn logiikan unohtaen, mihin malli on tarkoitettu MVC-mallissa.

    MVC PHP:ssä

    Ehdotan, että yrität toteuttaa yllä mainitun pienessä sovelluksessa. Aloitetaan luomalla malli-, näkymä- ja ohjainluokat: