MVC architectonisch patroon. Een vriendelijke benadering van webontwikkeling: MVC-model

Patroon Model-View-Controller (MVC), ontdekt eind jaren zeventig, is een architectuurontwerppatroon software, waarvan de belangrijkste taak is om de functies van het werken met gegevens te scheiden van hun presentatie. Theoretisch zal een goed ontworpen MVC-applicatie ervoor zorgen dat front-end- en back-end-ontwikkelaars zich tijdens hun werk niet met elkaars verantwoordelijkheidsgebieden bemoeien, dat wil zeggen dat de front-end-ontwikkelaar niets hoeft te weten over de "keuken" van zijn back-end collega en vice versa.

Hoewel MVC oorspronkelijk is ontworpen voor de ontwikkeling van desktopapplicaties, is het aangepast voor moderne taken en is enorm populair onder webontwikkelaars, omdat het door de verdeling van verantwoordelijkheden mogelijk is geworden om een ​​duidelijker, gebruiksklaar hergebruiken code. Het MVC-patroon resulteert in schone, modulaire systemen waarmee ontwikkelaars zeer snel wijzigingen in bestaande code kunnen aanbrengen.

In dit artikel zullen we kijken basisprincipes MVC, beginnend met het definiëren van een patroon en dit verder toepassen in een klein voorbeeld. Dit artikel zal vooral nuttig zijn voor degenen die dit patroon nog nooit in hun leven zijn tegengekomen, en misschien ook voor degenen die hun kennis van MVC willen opfrissen.

MVC begrijpen

Zoals reeds vermeld komt de naam van het patroon voort uit een afkorting van drie woorden: Model (model), Weergave En Controleur. In het kort kan het werkingsprincipe van het patroon worden geïllustreerd met één diagram (te vinden op Wikipedia):

Dit diagram toont duidelijk de unidirectionele informatiestroom in het patroon en beschrijft ook de rollen van elke component.

Model

Het model wordt gebruikt om toegang te krijgen tot gegevens en deze te manipuleren. In de meeste gevallen wordt het model gebruikt om toegang te krijgen tot de gegevensopslag (zoals een database). Het model biedt een interface voor het zoeken naar gegevens, het maken ervan, het wijzigen ervan en het verwijderen van gegevens uit de opslag. In de context van het patroon MVC-model is een tussenpersoon tussen de weergave en de controller.

Een uiterst belangrijk kenmerk van een model is dat het technisch gezien geen kennis heeft van wat er met de gegevens in de controller en weergave gebeurt. Het model mag nooit verzoeken naar/van andere patrooncomponenten doen of erop wachten.

Houd er echter altijd rekening mee dat het model niet slechts een toegangspoort is tot een database of ander systeem dat niets anders doet dan gegevens heen en weer overbrengen. Een model is als een toegangspoort tot de gegevens. Het model is in de meeste gevallen het meest complexe onderdeel van het systeem, mede doordat het model zelf de verbindende schakel is voor alle andere onderdelen.

Prestatie

De weergave is waar de gegevens die van het model worden ontvangen, worden uitgevoerd in de juiste vorm. In traditionele webapplicaties die zijn ontwikkeld met behulp van het MVC-patroon, is de weergave het deel van het systeem waar de HTML-code wordt gegenereerd. De weergave is ook verantwoordelijk voor het ontvangen van acties van de gebruiker om deze naar de controller te sturen. In een weergave wordt bijvoorbeeld een knop weergegeven gebruikersinterface en nadat u erop hebt gedrukt, wordt de overeenkomstige actie van de controller uitgevoerd.

Er bestaan ​​enkele misvattingen over het doel van een weergave, vooral onder webontwikkelaars die net beginnen met het bouwen van hun applicaties met MVC. Een van de meest vaak overtreden regels is dat de weergave mag op geen enkele manier met het model communiceren, en dat is alles de door de view ontvangen gegevens mogen alleen afkomstig zijn van de controller. In de praktijk negeren ontwikkelaars dit concept, dat de kern vormt van het MVC-patroon, vaak. Het artikel van Fabio Cevasco illustreert deze verwarrende benadering van MVC met behulp van CakePHP, een van de vele niet-standaard MVC-frameworks:

Het is uiterst belangrijk om te begrijpen dat er, om een ​​goede MVC-architectuur te krijgen, geen directe interacties tussen views en modellen mogen plaatsvinden. Alle logica voor het uitwisselen van gegevens tussen hen moet in controllers worden geïmplementeerd.

Bovendien bestaat er een algemene misvatting dat een weergave slechts een sjabloonbestand is. Zoals Tom Butler opmerkte, is deze misvatting enorm vanwege het feit dat veel ontwikkelaars de MVC-structuur vanaf het allereerste begin verkeerd begrijpen, waarna ze deze ‘kennis’ verder in de massa beginnende ontwikkelaars beginnen te gieten. In werkelijkheid is een weergave veel meer dan alleen een sjabloon, maar veel raamwerken die bovenop het MVC-patroon zijn gebouwd, hebben het concept van een weergave zo vervormd dat het niemand uitmaakt of hun toepassingen correct zijn in termen van het MVC-patroon.

Ook belangrijk punt is dat de weergave nooit werkt met "pure" gegevens van de controller, dat wil zeggen dat de controller nooit met de weergave werkt zonder het model te omzeilen. Tijdens de interactie tussen de controller en de weergave moet het model zich altijd tussen hen in bevinden.

Controleur

De controller is het laatste onderdeel van de MVC-bundel. De taak van de controller is om gegevens van de gebruiker te ontvangen en het model te manipuleren. Het is de controller, en alleen hij, die het deel van het systeem is dat met de gebruiker communiceert.

In een notendop kan een controller worden omschreven als een informatieverzamelaar die deze doorgeeft aan het model voor verwerking en opslag. Het mag niets met de gegevens doen, maar alleen van de gebruiker kunnen ontvangen. De controller is gekoppeld aan één weergave en één model, waardoor een unidirectionele gegevensstroom wordt georganiseerd en deze in elke fase wordt gecontroleerd.

Het is erg belangrijk om te onthouden dat een controller zijn werk pas begint als resultaat van gebruikersinteractie met de weergave, die de bijbehorende controllerfunctie aanroept. De meest voorkomende fout onder ontwikkelaars is dat ze de controller eenvoudigweg zien als een poort tussen de weergave en het model. Als gevolg hiervan wordt de controller begiftigd met de functies die door de weergave moeten worden uitgevoerd (dit is trouwens waar het idee vandaan komt dat een weergave slechts een sjabloonbestand is). Bovendien dumpen veel mensen alle logica van gegevensverwerking volledig en vergeten ze waarom MVC-patroon model is bedoeld.

MVC in PHP

Ik stel voor om het bovenstaande in een kleine applicatie te implementeren. Laten we beginnen met het maken van de model-, view- en controller-klassen:

string = "MVC + PHP = Geweldig!";))

controleur = $controleur;

"; } } $dit->

" . $dit->model->string . "

model = $model;

))

De hoofdklassen zijn klaar. Laten we ze nu aan elkaar koppelen en onze applicatie uitvoeren:

uitvoer();Zoals u kunt zien, heeft de controller geen functionaliteit omdat de gebruiker op geen enkele manier interactie heeft met de applicatie. Alle functionaliteit wordt in de weergave geplaatst, aangezien onze applicatie uitsluitend bedoeld is voor het weergeven van gegevens.

Laten we de applicatie een beetje uitbreiden door wat interactiviteit toe te voegen om te zien hoe de controller werkt:

"; } } string = “MVC + PHP = Geweldig, klik hier!”;

En tot slot, laten we de verbindingscode enigszins moderniseren:

($_GET["actie"])(); ) echo $view->output();

Resultaten

In dit korte artikel hebben we de basisconcepten van het MVC-ontwerppatroon bekeken en op basis daarvan een eenvoudige applicatie ontwikkeld, hoewel we er uiteraard nog ver verwijderd van zijn om het in de praktijk te gebruiken. In het volgende artikel zullen we kijken naar de belangrijkste problemen die u zult tegenkomen als u meer betrokken raakt bij het bouwen van een applicatiearchitectuur op basis van het MVC-patroon. Blijf op de hoogte!

In dit artikel zullen we het concept van MVC begrijpen en hoe we het, aan de hand van een voorbeeld, in PHP kunnen toepassen.

MVC-concept

MVC(Model-view-controller, " Model-View-Gedrag», « Model-View-Controller") is een applicatieontwerppatroon waarin de besturingslogica is verdeeld in drie afzonderlijke componenten, zodat het wijzigen van één ervan een minimale impact heeft op de andere.

De MVC-sjabloon is goed te gebruiken bij het maken van complexe projecten waarbij het nodig is om het werk van een PHP-programmeur (of een groep programmeurs in afdelingen op te delen), ontwerper, lay-outontwerper, enz. te scheiden.

Het MVC-patroon scheidt de verwerking van presentatie, gegevens en gebruikersinteractie in drie afzonderlijke componenten:

MVC-model(Model). Het Model levert gegevens (meestal aan de View) en reageert ook op verzoeken (meestal van de Verwerkingsverantwoordelijke) door de status ervan te wijzigen.

MVC-weergave(Weergave). Verantwoordelijk voor het weergeven van informatie (gebruikersinterface).

MVC-gedrag(controleur). Interpreteert gebruikersinvoer en informeert het model en de weergave om dienovereenkomstig te reageren.

Ter verduidelijking van het actiediagram van de MVC-sjabloon vindt u hieronder een illustratie.

Componenten zoals presentatie en gedrag zijn afhankelijk van het model, maar hebben er geen enkele invloed op. Een model kan meerdere weergaven hebben. Het concept van MVC is misschien moeilijk te begrijpen, maar als je het eenmaal begrijpt, wordt het onmisbaar bij het ontwikkelen van applicaties in PHP.

MVC in PHP

Bijzonder bij het gebruik van MVC in PHP is dat er één toegangspunt is tot de PHP-applicatie, die bijvoorbeeld als volgt wordt bereikt. Er wordt een index.php gemaakt waarmee alle verzoeken worden verwerkt. Om dit te doen, maakt u een .htaccess-bestand aan in de map met de index en plaatst u de volgende code daarin:

RewriteEngine op RewriteCond %(REQUEST_FILENAME) !-f RewriteCond %(REQUEST_FILENAME) !-d RewriteRule ^(.*)$ index.php?route=$1

In de meegeleverde code controleert de eerste regel het bestaan ​​van het gevraagde bestand, en als het niet bestaat, wordt het doorgestuurd naar index.php, anders worden zelfs verzoeken om site-afbeeldingen doorgestuurd naar de index. De laatste coderegel converteert verzoeken zoals index.php?route=chat/index naar index.php/chat/index. Als u ModRewrite niet in uw toepassing kunt gebruiken, moet u de omleiding handmatig uitvoeren.

PHP-model

Gegevens over het PHP-model zijn vastgelegd in de attributen en kunnen alleen via speciale functies worden gewijzigd. Een model kan meerdere aanzichten bevatten. In de regel is een phpmodel een klasse die werkt met een database, meer specifiek: schrijven, lezen, verwijderen. Uiteraard kan het lezen van informatie uit de database via meerdere weergaven (functies) worden gerealiseerd. Als voorbeeld: een model van artikelen op een website: u kunt een specifiek artikel uit de database halen, een lijst met de nieuwste artikelen, populaire artikelen, een bepaalde categorie... dit zijn allemaal representaties van het model. Voor de duidelijkheid wordt hieronder een voorbeeld van een php-model gegeven.

PHP-controller (Gedrag)

PHP-controllers ontvangen gebruikersverzoeken die we via index.php hebben verzonden en passen in overeenstemming daarmee de werking van het model aan. Het zou juister zijn om te zeggen dat zij de werking van de PHP-applicatie controleren.

PHP-vertegenwoordiging

De weergave monitort veranderingen in het model en creëert of wijzigt de interface van de PHP-applicatie.

Lijst met gegevens

voornaam ?>

achternaam?>



Hoe werkt dit?PHPMVC-sjabloon?

Wanneer de gebruiker de vereiste url bezoekt, wordt de bijbehorende controller geselecteerd, die toegang krijgt tot de weergave en het model, en wordt informatie weergegeven. Met andere woorden: de controller in mvc is de verbindende schakel tussen het model en de weergave.

Voordelen van een MVC-template bij het maken van een PHP-applicatie

Zoals hierboven vermeld, is dit in de eerste plaats de differentiatie van PHP-site-ontwikkelaars in afdelingen. Ook neemt de snelheid van de PHP-applicatie toe als er een groot project wordt aangemaakt. Wat de PHP-ontwikkelaar zelf direct aangaat, is de juiste structurering van de PHP-code (alles staat op zijn plaats, dus het is gemakkelijker te begrijpen).

MVC-voorbeeld

We zullen ons niet te veel concentreren op het voorbeeld van hoe MVC werkt, aangezien we er al een hebben. Ik zal nog een paar diagrammen toevoegen voor een beter begrip.

Een ander schema voor hoe een MVC-sjabloon in PHP werkt, het is meer dan gemakkelijk te begrijpen.

In dit artikel zullen we het “framework” van ons project schrijven. Met ‘framework’ bedoel ik werkende code die gebaseerd zal zijn op de MVC-aanpak, dat wil zeggen dat het een duidelijke verdeling van de logica zal hebben in controllers, acties, sjablonen (views) en modellen.

En dus laten we beginnen, zoals ik al in het vorige artikel schreef, het MVC-patroon impliceert één toegangspunt - index.php, alle verzoeken zullen via dit script passeren, alle projectlogica zal er doorheen werken. Om deze aanpak te implementeren, is het noodzakelijk om de server te configureren. Er wordt aangenomen dat de site op de Apache-server draait, dus we hoeven alleen maar een .htaccess-bestand te maken waarin we de URL-routeringsregels zullen specificeren. Naast het bepalen van het toegangspunt kunt u met routing ook CNC's (door mensen leesbare URL's) maken. Dat wil zeggen dat na de juiste configuratie de paginaadressen er als volgt uit zullen zien: site.ru/article/new.
Laten we eerst .htaccess maken, waarmee de verwerking van alle pagina's wordt omgeleid naar het index.php-script. De code ziet er als volgt uit:

RewriteEngine op RewriteCond %(REQUEST_FILENAME) !-f RewriteCond %(REQUEST_FILENAME) !-d RewriteRule ^(.*)$ index.php?route=$1

Het .htaccess-bestand moet zich in de hoofdmap van de site bevinden en u moet onmiddellijk een index.php-script maken, wat het toegangspunt is. Laten we één regel in index.php schrijven om de omleiding te testen:

Echo "test";

Nu kunt u de omleiding controleren, een willekeurig adres invoeren en zien wat er gebeurt: test-mvc.web/sdf/sdf/ of test-mvc.web/sdf/sdf/2342/het maakt in ieder geval niet uit, “ Test ". Als je deze inscriptie hebt gezien, betekent dit dat het ons is gelukt.
Laten we voor het gemak doorgaan met het maken van een config.php-bestand in de hoofdmap van de site, waarin we verschillende constanten zullen instellen die het gemakkelijker maken om de site te configureren. Dit kunnen verschillende paden zijn naar scripts, databasebenaderingen, enzovoort. Laten we nu in de configuratie het volgende instellen:

// Stel de constanten in: definieer ("DS", DIRECTORY_SEPARATOR); // scheidingsteken voor bestandspaden $sitePath = realpath(mapnaam(__FILE__) . DS); definieer("SITE_PATH", $sitePath); // pad naar de hoofdmap van de site // om verbinding te maken met de database definition("DB_USER", "root"); definieer("DB_PASS", ""); definieer("DB_HOST", "localhost"); definieer("DB_NAME", "blog_mvc");

Om ervoor te zorgen dat we constanten en andere configuratiegegevens gedurende het hele project kunnen gebruiken, moeten we het config.php-script in het index.php-bestand opnemen.
Naast het verbinden van het instellingenbestand, moet u in index.php een verbinding maken met de database, het script verbinden met de sitekern en de router starten waarin de routering zal plaatsvinden.
Nu zal het maken van de databaseverbinding nu in index.php plaatsvinden, zodat de verbinding slechts één keer wordt geopend. Zodra we de verbinding hebben geopend, kunnen we deze in alle controllers en modellen gebruiken, maar daarover later meer. Laten we nu een verbinding met de database maken. Om met de database te werken, besloot ik PDO te gebruiken. U kunt meer lezen over PDO.
We plaatsen de kern van de site in de kernmap en noemen het script core.php, hier zullen we een functie schrijven die zelf verbinding maakt, klassen zijn nodig om te werken. Deze functie zal ons werk met controllers, modellen, enz. aanzienlijk vergemakkelijken en vereenvoudigen. Want vooruitkijkend zal ik zeggen dat elke controller en elk model een aparte klasse zal vertegenwoordigen.
Naast het automatisch verbinden van klassen, zullen we aan de kern het creëren van een repository (register) toevoegen, waarin we alle noodzakelijke objecten en variabelen opslaan die overal in het project nuttig kunnen zijn.
We zullen ook de router verbinden met het indexbestand, deze zal de URL analyseren en de nodige controller en actie verbinden. Wat een controller is, schreef ik in een vorig artikel en heb bewust informatie over de actie weggelaten, zonder deze te laden met onnodige informatie. Dus wat is actie?
Een controller is een klasse die verschillende methoden bevat; bij de MVC-aanpak zal elke methode een actie zijn. Dat wil zeggen dat een actie een klassenmethode is die gegevens verwerkt en overbrengt naar de weergave (naar de sjabloon). Het is misschien nog niet helemaal duidelijk, maar na het voorbeeld valt alles op zijn plek.
In dit stadium is de theorie voldoende, laten we verder gaan met de praktijk. Ik zal de code geven van de bestanden waarvan ik de werking hierboven heb beschreven.
Index.php-scriptcode:

// weergave van alle fouten error_reporting (E_ALL) inschakelen; // verbind de configuratie include ("/config.php"); // Verbinding maken met de database $dbObject = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME, DB_USER, DB_PASS); // verbind de kern van de site include (SITE_PATH . DS . "core" . DS . "core.php"); // Laad router $router = nieuwe router($registry); // schrijf gegevens naar het register $registry->set ("router", $router); // stel het pad in naar de map controllers. $router->setPath(SITE_PATH. "controllers"); //start de router $router->start();

Core.php-script:

// Klassen direct laden functie __autoload($className) ( $filename = strtolower($className) . ".php"; // definieer de klasse en vind het pad ervoor $expArr = explode("_", $className ) ; if(empty($expArr) OR $expArr == "Basis")( $folder = "klassen"; )else( switch(strtolower($expArr))( case "controller": $folder = "controllers"; break ; case "model": $map = "modellen"; standaard: $map; break ) // pad naar klasse $file = $filename; false; ) // neem het bestand op met de klasse include ($file ) // start het register (opslag) $registry = nieuw register;

De opslagklasse Registry.php bevindt zich in de map /classes/

// Opslagklasse Class Registry ( private $vars = array(); // gegevensopnamefunctie set($key, $var) ( if (isset($this->vars[$key]) == true) ( ​​​throw new Exception("Kan var `" niet instellen. $key. "`. Al ingesteld." ) $this->vars[$key] = $var return true; // gegevensfunctie get($key) ( if (isset($this->vars[$key]) == false) ( return null; ) return $this->vars[$key] ) // verwijder gegevensfunctie remove($var) ( unset($ this ->vars[$sleutel]);

Code van het router.php-bestand, dat zich in de map /classes/ bevindt

// router class Class Router ( private $registry; private $path; private $args = array(); // haal de opslagfunctie __construct($registry) op ( $this->registry = $registry; ) // stel het pad in naar de map met de controllerfunctie setPath($path) ( $path = trim($path, "/\\"); $path .= DS; // als het pad niet bestaat, geef dit dan aan als (is_dir($path ) == false ) ( throw new Exception ("Ongeldig controllerpad: `" . $path . "`"); ) $this->path = $path ) // definieer de controller en actie vanuit de privé-URL-functie getController( &$file, & $controller, &$action, &$args) ( $route = (leeg($_GET["route"])) ? "" : $_GET["route"]; unset($_GET[" route"]); if (empty($route)) ( $route = "index"; ) // Haal delen van de URL op $route = trim($route, "/\\"); $parts = explode(" /", $route); // Zoek de controller $cmd_path = $this->path; foreach ($parts as $part) ( $fullpath = $cmd_path . $part; // Controleer of de map bestaat als (is_dir( $fullpath)) ( $cmd_path .= $ part . DS; array_shift($parts);

doorgaan; ) // Zoek het bestand if (is_file($fullpath . ".php")) ( $controller = $part; array_shift($parts); break; ) ) // als de URL geen controller specificeert, gebruik dan de standaardindex if (leeg ($controller)) ( $controller = "index"; ) // Haal de actie op $action = array_shift($parts);
if (leeg($action)) ( $action = "index"; ) $file = $cmd_path . $controleur. ".php";

// controller Class Controller_Index breidt Controller_Base uit ( // template public $layouts = "first_layouts"; // action function index() ( $model = new Model_Users(); $userInfo = $model->getUser(); $this-> template->vars("userInfo", $userInfo); $this->template->view("index" ) )

Voor weergave(/views/index/index.php)

Testweergave
ID:
naam:

En het model:

// model Class Model_Users( public function getUser())( return array("id"=>1, "name"=>"test_name"); ) )

Zoals je misschien hebt gemerkt, erft de controllerklasse van de bovenliggende klasse Controller_Base. Dit wordt gedaan om de controllerklasse te vereenvoudigen. Omdat we de klasse nog steeds moeten verbinden om met sjablonen te werken, wordt de verbinding ervan in Controller_Base geplaatst.
Ik zal de code geven, deze bevindt zich in de map /classes/ en heet controller_base.php:

// abstracte controllerklasse Abstract Class Controller_Base ( protected $registry; protected $template; protected $layouts; // template public $vars = array(); // connect templates in de constructorfunctie __construct($registry) ( $this-> register = $registry; // sjablonen $this->template = nieuwe sjabloon($this->layouts, get_class($this) ) abstracte functie index();

Nu hoeft u alleen nog maar de sjablonen uit te zoeken. In de abstracte klasse Controller_Base noemen we de klasse Template en geven deze de naam van de sjabloon en de naam van de controller door.
De code voor de klasse Template, die zich hier /classes/ bevindt en template.php heet

// klasse voor het verbinden van sjablonen en het doorgeven van gegevens aan het display Class Template ( private $template; private $controller; private $layouts; private $vars = array(); function __construct($layouts, $controllerName) ( $this->layouts = $layouts; $arr = explode("_", $controllerName); $this->controller = strtolower($arr); // variabelen instellen om de functie vars($varname, $value) weer te geven ( if (isset ($this->vars[$varname]) == true) ( ​​trigger_error ("Kan var `" niet instellen. $varname . "`. Al ingesteld en overschrijven niet toegestaan.", E_USER_NOTICE); return false; ) $this ->vars[$varname] = $value; return true ) // weergavefunctie view($name) ( $pathLayout = SITE_PATH . "views" . DS . "layouts" . DS . $this->layouts . php"; $contentPage = SITE_PATH . DS . $this->controller .php"; " . $ this->layouts . "` bestaat niet.", E_USER_NOTICE); return false; if (file_exists($contentPage) == false) ( trigger_error ("Sjabloon `" . $naam . "` bestaat niet.", E_USER_NOTICE);

retour vals;
) foreach ($this->vars as $key => $value) ( ​​$$key = $value; ) include ($pathLayout);

))

Als je de code aandachtig hebt gelezen, realiseerde je je waarschijnlijk dat we voor weergave op de pagina's de sjabloon first_layouts en de view (display) index.php gebruiken - ik heb de code iets hoger gegeven. Het enige dat we nog hebben is het maken van het first_layouts-sjabloonbestand. Laten we het in de map /views/layouts/first_layouts.php plaatsen

De sjabloon bevat de volgende code:
koptekst

voettekst Dat is alles, dit voltooit de creatie van het "framework". Nu hebben we de eenvoudigste structuur gebaseerd op het MVC-patroon. In dit artikel ging ik niet in op het werken met de database, ik noemde het alleen terloops, aangezien het artikel al lang was. In het volgende artikel zal ik het werken met de database direct beschrijven. Dit artikel is klaar, je kunt de bronbestanden downloaden in het archief. In het patroon " Model - Weergave - Controller

Een weergave is een visuele weergave van de gegevens in een model. Een subset van het model bevindt zich in een afzonderlijke weergave, zodat de weergave als filter voor de modelgegevens fungeert. De gebruiker communiceert met de modelgegevens via de visuele weergave die de weergave biedt en heeft toegang tot de bedrijfslogica, die op zijn beurt de modelgegevens beïnvloedt.

De controller verbindt de weergave met het model en beheert de datastroom van de applicatie. Het selecteert welke weergave aan de gebruiker moet worden weergegeven als reactie op de invoer van de gebruiker en op basis van de bedrijfslogica die wordt uitgevoerd. De controller ontvangt het bericht van de weergave en stuurt deze door naar het model. Het model bereidt op zijn beurt een antwoord voor en stuurt ero terug naar de controller, waar de weergave wordt geselecteerd en ero naar de gebruiker wordt gestuurd.

MVC-patroon omvat logischerwijs de client- en middenlaag van een architectuur met meerdere lagen. In de Java-omgeving bevindt het EE-model zich in de bedrijfslaag, meestal in de vorm van een EJB-module.

De controller en weergave bevinden zich in de weblaag. De weergave zal hoogstwaarschijnlijk worden gemaakt van JavaServer-gezichten(JSF) of JavaServer-pagina's(JSP) met behulp van Expression Language (EL). De controller is meestal een servlet die HTTP-verzoeken van de gebruiker ontvangt.

MVC wordt vaak gecombineerd met andere patronen zoals Commando (of Actie), Strategie, Composer en " ".

Dit patroon werd voor het eerst genoemd vóór de creatie van het internet in zijn moderne vorm, in een artikel dat in december 1979 werd gepubliceerd door Trygve Reenskaug, een programmeur die toen bij Xeror SmallTalk werkte.

En hoewel de MVC-elementen van dit patroon meer dan 35 jaar geleden werden beschreven, komen ze verrassend goed overeen met hun moderne gebruik in webapplicaties.

De volgende afbeelding toont een gebruiker die een verzoek indient bij een controller. De controller verwerkt het verzoek door het model bij te werken en een nieuwe weergave weer te geven, die vervolgens naar de gebruiker wordt verzonden.

MVC-patroondiagram

MVC-patroon bestaat in veel verschillende vormen. De twee bekendste worden meestal genoemd typ ik En type II.

MVC-patroontypen:

  • MVC type I. Dit type is een paginagerichte benadering waarbij de weergave en de controller bestaan ​​als één enkele entiteit, de viewcontroller. Bij deze aanpak wordt de controllerlogica geïmplementeerd in een weergave zoals JSF. Alle taken die door de controller worden uitgevoerd, inclusief het ophalen van HTTP-verzoekkenmerken en -parameters, het aanroepen van bedrijfslogica en het beheren van de HTTP-sessie, zijn in de weergave ingebouwd met behulp van scriptlets en tagbibliotheken. Type I koppelt de vorming van het zicht sterk aan de volgorde van handelingen die de applicatie uitvoert, waardoor onderhoud lastig wordt.
  • MVC type II. De onderhoudbaarheidsproblemen van Type I worden bij Type II overwonnen door de controllerlogica uit de weergave en naar de servlet te verplaatsen, waardoor de datavisualisatie aan de weergave wordt overgelaten.

Het belangrijkste verschil tussen Type I en Type II is de locatie van de controllerlogica: bij Type I bevindt deze zich in de weergave, en bij Type II bevindt deze zich in de servlet.

Veel raamwerken zoals Lente MVC, Stutten, Grails En Wicket, implementeren hun eigen versie van het MVC Type II-patroon. Bijvoorbeeld, Lente MVC omvat het concept van een dispatcherservlet die interageert met HTTP-verzoeken en delegatie naar de controller uitvoert, en bevat ook een view (en view-resolver) en handlers.

De volgende afbeelding toont een implementatiediagram van het MVC-patroon in Spring.

Diagram van de implementatie van het MVC-patroon in het voorjaar

Hoewel de betekenis van de uitdrukking 'site-architectuur' misschien intuïtief voor u is, laten we proberen het te bestuderen een aantal definities uit gezaghebbende bronnen.

Architectuur- dit is de basisorganisatie van het systeem, belichaamd in zijn componenten, hun relaties met elkaar en met de omgeving, evenals de principes die het ontwerp en de ontwikkeling van het systeem bepalen.

Architectuur een programma of computersysteem is de structuur of structuren van een systeem dat elementen van het programma omvat, de extern zichtbare eigenschappen van deze elementen en de relaties daartussen [Bass].

Architectuur is de structuur van de organisatie en het gedrag van het systeem dat daarmee verbonden is. Een architectuur kan recursief worden ontleed in onderdelen die op elkaar inwerken via interfaces, verbindingen die de onderdelen met elkaar verbinden, en voorwaarden voor het samenstellen van de onderdelen. De onderdelen die via interfaces met elkaar communiceren, omvatten klassen, componenten en subsystemen.

Architectuur Een softwaresysteem of een reeks systemen bestaat uit alle belangrijke ontwerpbeslissingen over de programmastructuren en de interacties tussen die structuren waaruit de systemen bestaan. Ontwerpbeslissingen bieden een gewenste reeks eigenschappen die een systeem moet ondersteunen om succesvol te zijn. Ontwerpoplossingen vormen de conceptuele basis voor systeemontwikkeling, ondersteuning en onderhoud.

Dus wat is programma-architectuur?

De definities die in de vorige sectie zijn gegeven, zijn te droog voor de onvoorbereide lezer om waar te nemen. We zullen proberen de essentie zo eenvoudig mogelijk uit te leggen.

Wanneer een programma groot genoeg wordt, splitst de programmeur het in verschillende bestanden. Als je er niet aan denkt om groepen met vergelijkbare functies te identificeren en deze in afzonderlijke modules te plaatsen, heeft een dergelijke indeling weinig nut. De code zal niet herbruikbaar zijn en zal moeilijk te navigeren zijn. Het programma zal moeilijk uit te breiden en te veranderen zijn.

Zo rijst de eerste vraag: hoe het programma in bestanden te splitsen. De bestandsarchitectuur van een programma is één aspect van de structuur ervan.

Bij het identificeren van systeemmodules is het noodzakelijk om de relatie tot elkaar te begrijpen waarin ze zich bevinden. Het is bijvoorbeeld onwaarschijnlijk dat modules voor databasetoegang en grafische verwerking iets van elkaars bestaan ​​weten. Maar de UI-module zal van beide op de hoogte zijn (en zij zullen er niets van weten).

De relaties tussen systeemcomponenten worden ook bepaald door de architectuur ervan.

Over het algemeen kunnen alle belangrijke beslissingen die gericht zijn op het organiseren van het programma, en niet op de problemen die met de hulp ervan zijn opgelost, worden toegeschreven aan architectuur.

Niveaus van abstractie

Bij het ontwerpen van modules (het selecteren van groepen functies en deze in bestanden distribueren in het geval van een procedurele benadering) is het belangrijk om abstracties te benadrukken en te proberen deze in verschillende niveaus op te splitsen.

Modules op een laag niveau zijn zo autonoom mogelijk; ze zijn niet afhankelijk van andere delen van het programma. Goed ontworpen modules isoleren de ‘buitenwereld’ van de complexiteit van het oplossen van het hen toegewezen probleem. De bellende partij kent alleen de module-interface (externe functies), het interne deel is daarvoor gesloten.

Laten we als voorbeeld een fotogalerij nemen. Informatie over afbeeldingen en gebruikers wordt opgeslagen in de database, de gebruikersinterface is verdeeld in een clientgedeelte en een beheerderspaneel.

De programmastructuur zou er als volgt uit kunnen zien:


Dit voorbeeld sporen drie abstractieniveaus.

In elk programma dat bedoeld is voor menselijk gebruik zijn er minstens twee niveaus: de gebruikersinterface en het model. De gebruikersinterfacemodule is ontworpen om gegevens te presenteren en te visualiseren en gebruikersreacties te verwerken. Het model bevat de logica van het probleem dat wordt opgelost en mag op geen enkele manier afhankelijk zijn van de manier waarop de gegevens worden weergegeven. Het model moet gemakkelijk overdraagbaar zijn tussen verschillende soorten gebruikersinterfaces.

MVC-architectuur

Populair nu MVC-ontwerppatroon. Het dient om de applicatielogica te scheiden van de gebruikersinterface. Maar laten we eerst verduidelijken wat een ontwerppatroon is.

Dit is een reeks standaardontwerpoplossingen, een architectuurraamwerk of een fragment daarvan. Als een bibliotheek een pakket herbruikbare code is, dan is een ontwerppatroon een pakket herbruikbare oplossingen.

Wat biedt MVC ons om applicatielogica te scheiden van de gebruikersinterface?

Steekproef Met MVC kunt u scheiden gegevens, presentatie en verwerking van gebruikersacties in drie afzonderlijke componenten:

  1. Model. Het Model levert gegevens (meestal aan de View) en reageert ook op verzoeken (meestal van de Verwerkingsverantwoordelijke) door de status ervan te wijzigen;
  2. Weergave. Verantwoordelijk voor het weergeven van informatie (gebruikersinterface);
  3. Controleur. Interpreteert gebruikersinvoer en informeert het model en de weergave om op de juiste manier te reageren.

In onderstaande figuur zijn de relaties tussen de onderdelen van het raamwerk weergegeven. Laten we de figuur illustreren met een klein voorbeeld.


Stel je een formulier voor waarin je tekst kunt invoeren, klik op de knop Bewerken en krijg de transliteratie:


Laten we de stappen herhalen die in het diagram worden weergegeven:

  1. De gebruiker drukt op de knop Bewerken en Prestatie(Bekijken) stuurt een bericht Naar de controleur(Controller): "Opdracht: bewerken"
  2. De controleur accepteert bericht en opent het model door de methode Edit() aan te roepen.
  3. Als resultaat het model verandert de staat ervan (de getranslitereerde tekst die erin is opgeslagen) en informeert de weergave hierover: "Gebeurtenis: gewijzigd".
  4. Inzending accepteert signal en neemt contact op met het model voor een nieuwe resultaatwaarde door de Get() -methode aan te roepen.

MVC-implementatie

De implementatie van MVC gaat uit van een objectgeoriënteerde benadering (OOP). Een ontwerppatroon is echter slechts een reeks oplossingen. Laten we ze aanpassen voor PHP zonder OOP te gebruiken. Vereenvoudiging wordt gedaan om zich te concentreren op de essentie van de scheiding van logica, en ook zodat het materiaal kan worden toegepast door een lezer die niet bekend is met OOP.

Laten we nog eens kijken bijvoorbeeld met een fotogalerij.
Het heeft twee weergavemodi:

  1. Modus voor het bekijken van miniatuurafbeeldingen (allemaal tegelijk);
  2. Modus voor het bekijken van een foto op volledig formaat (één).

Het is ook mogelijk foto's uploaden naar de server. Daarnaast zullen we ondersteuning voor visualisatietypen implementeren om de flexibiliteit van het raamwerk te evalueren.

Dat zal zo zijn twee instappunten:

  1. index.php(galerijweergave);
  2. photo.php (bekijk foto op volledige grootte).
We zullen deze twee bestanden bekijken Controleurs.

Als Modellen wordt een module die werk biedt met beeldopslag. Laten we hem bellen galerij.php en plaats het in een map model.

In de rol Inzendingen Er verschijnen HTML-sjablonen, deze bevinden zich in de map sjablonen. Wat sjablonen zijn en waarvoor ze nodig zijn, zul je later zien.

De galerijweergave en fotoweergavepagina's zullen een gemeenschappelijke kop- en voettekst hebben; alleen het centrale gedeelte zal verschillen.

De galerijweergave heeft twee soorten visualisaties:

  1. Als tabel (standaard);
  2. In de vorm van een lijst.
We hebben vier sjablonen nodig:
  1. main.php(paginaframework);
  2. content_index_table.php (tabelweergave van de galerijinhoud);
  3. content_index_list.php (lijstweergave van galerijinhoud);
  4. content_photo.php (inhoud van de fotoweergavepagina).

Dit resulteert in de volgende sitestructuur:


De bestandsstructuur is verdeeld door twee horizontale balken, waardoor er drie secties ontstaan. De bovenste sectiebestanden behoren tot het Model, de middelste sectiebestanden tot de View en de onderste sectiebestanden tot de Controller.

Model

Laten we beginnen met de implementatie van het model. De onderstaande code wordt niet volledig weergegeven om het voorbeeld te minimaliseren en duidelijker te maken.

We hebben alleen de interface van het model gedefinieerd, waardoor de implementatie ontbreekt. Voor de voorbeeldimplementatie van het MVC-framework is dit echter helemaal niet nodig.

Prestatie

Laten we nu naar de sjablonen kijken. Laten we beginnen met het algemene paginaframe:

<?=$title?>



U moet niet in de war raken door het feit dat de sjabloon de variabelen $title en $content gebruikt die uit het niets komen. De controller zal ze instellen. Maar daarover later meer.

- dit is een verkorte versie van de notatie .

Het is handig om in sjablonen te gebruiken. Het is ook handiger om alternatieve opties te gebruiken voor het schrijven van de if-else-, foreach-, for- en while-constructies in sjablonen. Ze zien er zo uit:

Als (<условие>): <тело>eindals; foreach(<инициализация цикла>): <тело>eindigen;

De rest van de sjablonen worden als volgt in main.php ingevoegd:

De onderstaande voorbeelden tonen hun code:

Codesjablonen/content_index_table.php

Tafel| Lijst

"> " />



Codesjablonen/content_index_list.php

Tabel | Lijst

"> " />



templates/content_photo.php: Terug

" />

Controleur

En tot slot, laten we het allemaal samenvatten door onze twee controllers te beschrijven. Hun taak is om het verzoek te verwerken, een sjabloon te selecteren en de benodigde gegevens voor de sjabloon te vervangen. Gegevens worden meestal uit het model gehaald.

De galerijcontroller laadt de foto als de gebruiker een bestand heeft ingediend. Anders haalt het een lijst met foto's uit het model, selecteert het gewenste sjabloon (afhankelijk van de wens van de gebruiker) en geeft dit sjabloon weer, waarbij het een lijst met foto's doorgeeft:

Code-index.php

De fotoweergavecontroller is nog eenvoudiger:

Codeer foto.php

Tot slot

Probeer voldoende aandacht te besteden aan het ontwikkelen van de architectuur van uw applicatie. Als u in eerste instantie een sterk en uitbreidbaar frame creëert, de inspanning zal vruchten afwerpen honderdvoudig.

Om het MVC-model te implementeren, is het beter om te kiezen objectgeoriënteerde aanpak .

Er zijn veel kant-en-klare raamwerkoplossingen, bijvoorbeeld in Zend Framework. De informatie uit de huidige les is echter voldoende om architectuuroplossingen van MVC te begrijpen en deze nu te gaan gebruiken.