MVC för Noobs

Model-View-Controller (MVC) är antagligen en av de mest citerade mönster i webbprogrammeringsvärlden de senaste åren. Den som arbetar med något som är relaterat till webbapplikationsutveckling kommer ha hört eller läst akronym hundratals gånger. Idag kommer vi att klargöra vad MVC betyder, och varför det har blivit så populärt.

Antik historia…

MVC är inte ett designmönster, det är ett arkitektoniskt mönster som beskriver ett sätt att strukturera vår applikation och ansvar och interaktioner för varje del i den strukturen.

Det beskrivs först 1979 och uppenbarligen var kontextet lite annorlunda. Begreppet webbapplikation existerade inte. Tim Berners Lee sådde frön från World Wide Web i början av nittiotalet och förändrade världen för alltid. Mönstret vi använder idag för webbutveckling är en anpassning av det ursprungliga mönstret.

Den vilda populariseringen av denna struktur för webbapplikationer beror på att den ingår i två utvecklingsramar som blivit oerhört populära: Struts och Ruby on Rails. Dessa två miljöer markerade vägen för de hundratals ramar som skapades senare.

MVC för webbapplikationer

Tanken bakom arkitekturmönstret Model-View-Controller är enkelt: vi måste ha följande ansvarsområden klart separerade i vår applikation:

Ansökan är uppdelad i dessa tre huvudkomponenter, var och en ansvarig för olika uppgifter. Låt oss se en detaljerad förklaring och ett exempel.

Kontrollant

De Kontrollant hanterar användarbegäran (mottaget som HTTP GET eller POST-förfrågningar när användaren klickar på GUI-element för att utföra åtgärder). Huvudfunktionen är att ringa och samordna nödvändiga resurser / objekt som behövs för att utföra användarhandlingen. Normalt kommer regulatorn att ringa den lämpliga modellen för uppgiften och väljer sedan rätt vy.

Modell

De Modell är uppgifterna och reglerna som gäller för dessa data, vilka representerar begrepp som applikationen hanterar. I något mjukvarusystem modelleras allt som data som vi hanterar på ett visst sätt. Vad är en användare, ett meddelande eller en bok för en ansökan? Endast data som måste hanteras enligt specifika regler (datum kan inte vara i framtiden, e-post måste ha ett visst format, namn får inte vara mer än x tecken långt osv.).

Modellen ger regulatorn en datarrepresentation av vad användaren begärde (ett meddelande, en lista med böcker, ett fotoalbum, etc.). Denna datamodell kommer att vara densamma oavsett hur vi kanske vill presentera det för användaren, det är därför vi kan välja vilken tillgänglig vy som helst för att göra det.

Modellen innehåller den viktigaste delen av vår applikationslogik, den logik som gäller det problem vi hanterar (ett forum, en butik, en bank, etc.). Kontrollenheten innehåller en mer intern organisatorisk logik för själva applikationen (mer som hushållning).

Se

De Se tillhandahåller olika sätt att presentera de mottagna data från modellen. De kan vara mallar där uppgifterna är fyllda. Det kan finnas flera olika åsikter och regulatorn måste bestämma vilken som ska användas.

En webbapplikation består vanligtvis av en uppsättning kontroller, modeller och visningar. Styrenheten kan vara strukturerad som en huvudkontroller som tar emot alla förfrågningar och kräver specifika styrenheter som hanterar åtgärder för varje enskilt fall.

Låt oss se ett exempel

Antag att vi utvecklar en online bokhandel. Användaren kan utföra handlingar som: visa böcker, registrera, köpa, lägga till objekt i nuvarande ordning, skapa eller ta bort böcker (om han är administratör, etc.). Låt oss se vad som händer när användaren klickar på fantasi kategori för att se titlarna som vi har tillgängliga.

Vi kommer att ha en särskild kontroller för att hantera alla böckerrelaterade åtgärder (se, redigera, skapa osv.). Låt oss kalla det books_controller.php för det här exemplet. Vi kommer också att ha en modell, till exempel book_model.php, hantering av data och logik relaterad till föremålen i butiken. Slutligen kommer vi att ha en rad synpunkter för att presentera till exempel en lista med böcker, en sida för att redigera böcker etc..

Följande bild visar hur användarförfrågan om att visa listan över fantasiböcker hanteras:

Kontrollern (books_controller.php) tar emot användarbegäran [1] som HTTP GET eller POST-förfrågan (vi kan också ha en central kontroller, till exempel index.php tar emot den och sedan ringer books_controller.php).

Kontrollern undersöker begäran och parametrarna och kallar modellen (book_model.php) be honom att återvända listan över tillgängliga fantasy böcker [2].

Modellen ansvarar för att få den informationen från databasen (eller var den är lagrad) [3], tillämpa filter eller logik om det behövs, och returnera data som representerar listan över böcker [4].

Kontrollern använder lämplig vy [5] för att presentera dessa data för användaren [6-7]. Om förfrågan kom från en mobil, kommer en visning för mobiltelefoner att användas, om användaren har en viss hud vald, kommer motsvarande vy att väljas och så vidare.

Vad är fördelarna?

Den mest uppenbara fördelen vi får genom att använda MVC är en tydlig separation av presentation (gränssnittet med användaren) och applikationslogiken.

Stöd för olika typer av användare som använder olika typer av enheter är idag ett vanligt problem. Gränssnittet som presenteras måste vara annorlunda om begäran kom från en stationär dator eller från en mobiltelefon. Modellen returnerar exakt samma data, den enda skillnaden är att regulatorn kommer att välja en annan vy för att göra dem (vi kan tänka på en annan mall).

Förutom att isolera utsikten från affärslogiken minskar M-V-C-separationen komplexiteten vid utformning av stora applikationer. Koden är mycket mer strukturerad och är därför lättare att underhålla, testa och återanvända.

Ok, men varför en ram?

När du använder en ram är den grundläggande strukturen för MVC redan förberedd och du måste bara utöka den strukturen och placera dina filer i lämplig katalog för att överensstämma med modell-View-Controller-mönstret. Du får också en hel del funktionalitet som redan skrivits och testats grundligt.

Ta cakePHP som ett exempel MVC-ramverk. När du har installerat det ser du tre huvudkataloger:

  • app/
  • kaka/
  • säljare/

De app mappen är där du placerar dina filer. Det är din plats att utveckla din del av ansökan.

De kaka mapp är där cakePHP har sina filer och var de har utvecklat sin del (huvudramfunktionalitet).

De säljare mappen är för PHP-bibliotek från tredje part om det behövs.

Din arbetsplats (appkatalog) har följande struktur:

  • app/
    • config /
    • controllers /
    • locale /
    • modeller /
    • plugins /
    • test /
    • tmp /
    • säljare/
    • visningar /
    • webroot /

Nu måste du sätta dina controllers i controllers katalog, dina modeller i modeller katalog och dina synpunkter i ... the visningar katalog!

När du väl blivit van vid din ram kan du veta var du ska leta efter nästan vilken kod du behöver ändra eller skapa. Den här organisationen ensam gör att underhållet blir mycket enklare.

Låt oss ramma vårt exempel

Eftersom denna handledning inte är avsedd att visa dig hur du skapar en applikation med cakePHP, använder vi den bara för att visa exempelkod för modell, visa och kontroller-komponenter och kommentera fördelarna med att använda en MVC-ram. Koden är förenklad och inte lämplig för verkliga applikationer.

Kom ihåg att vi hade en bokhandel och en nyfiken användare som vill se hela listan med böcker i fantasi kategori. Vi sa att regulatorn kommer att vara den som tar emot förfrågan och samordnar nödvändiga åtgärder.

Så när användaren klickar begär webbläsaren denna webbadress:

 www.ourstore.com/books/list/fantasy

CakePHP gillar att formatera webbadresser i formuläret / controller / action / param1 / param2, var verkan är funktionen att ringa inom styrenheten. I det gamla klassiska urlformatet skulle det vara:

 www.ourstore.com/books_controller.php?action=list&category=fantasy

Kontrollant

Med hjälp av cakePHP-ramverket ser vår controller ut något liknande:

 set ('books', $ this-> Book-> findAllByCategory ($ category));  funktion add () ... funktion delete () ... ...?>

Enkelt, eller hur? Denna kontroller sparas som books_controller.php och placeras i / app / controllers. Den innehåller listfunktionen, för att utföra åtgärden i vårt exempel, men även andra funktioner för att utföra andra bokrelaterade åtgärder (lägg till en ny bok, ta bort en ny bok, etc.).

Ramverket ger en hel del saker för oss och endast en rad är nödvändig för att lista böckerna. Vi har basklasser med grundkontrollen som redan definierats, så vi ärver från dem (AppController som ärar från Controller).

Allt man behöver göra i listan är att ringa modellen för att få data och sedan välja en vy för att presentera den för användaren. Låt oss förklara hur det här görs.

this-> Bok är vår modell, och den här delen:

 $ This-> Bok> findAllByCategory ($ kategori)

berättar modellen för att returnera listan med böcker i den valda kategorin (vi ser modellen senare).

De uppsättning metod i linjen:

 $ this-> set ('books', $ this-> Book-> findAllByCategory ($ category));

Är regulatorn sätt att skicka data till vyn. Det ställer in böcker variabel till de data som returneras av modellen och gör den tillgänglig för vyn.

Nu måste vi bara göra vyn, men det görs automatiskt av cakePHP om vi vill ha standardvyn. Om vi ​​behöver någon annan syn behöver vi bara kalla det explicit med hjälp av göra metod.

Modell

Modellen är ännu enklare:

Varför tom? Eftersom det ärar från en basklass som ger nödvändig funktionalitet och vi har följt CakePHP-namnkonventionerna för att tillåta ramverket att göra andra uppgifter automatiskt. CakePHP vet till exempel, baserat på namn, att denna modell används i BooksController och att den kommer att få tillgång till en databas tabell som heter böcker.

Med denna deklaration har vi bara en bokmodell som kan läsa, radera eller spara data från databasen

Koden kommer att sparas som book.php och placeras i / app / modeller.

Se

Allt vi behöver göra nu skapar en vy (minst en) för liståtgärden. Vyn kommer att ha HTML-koden och ett fåtal (så få som möjligt) PHP-linjer att slinga genom böckerna som tillhandahålls av modellen.

Titel Författare Pris

Som vi kan se visar inte vyn en komplett sida, bara ett HTML-fragment (ett bord i det här fallet). Detta beror på att CakePHP ger ett annat sätt att definiera sidans layout, och synpunkterna läggs in i den layouten. Ramverket ger oss också några hjälparobjekt som gör det enkelt att skapa gemensamma uppgifter när de skapar dessa HTML-utdrag (sätt in formulär, länkar, Ajax eller JavaScript).

Vi gör detta till standardvyn som sparar det som list.ctp (listan är åtgärdens namn och ctp betyder kakmallen) och placerar den i / app / visningar / böcker (inuti böcker eftersom det här är synpunkter på bokhanteringshandlingar).

Och detta kompletterar de tre komponenterna med hjälp av CakePHP-ramen!

Slutsats

Vi har lärt oss vad som förmodligen är det mest använda arkitektoniska mönstret idag. Vi måste vara medvetna om att när vi pratar om mönster i programmeringsvärlden talar vi om flexibla ramar som ska skräddarsys för det aktuella problemet. Vi kommer att hitta implementeringar som introducerar variationer i strukturen vi sett, men det viktiga är att i slutändan hjälper mönstret oss att uppnå en klar uppdelning mellan ansvar och bättre underhåll, kodåteranvändning och testning.

Vi har också sett fördelarna med att använda en MVC-ram som ger oss ett grundläggande MVC-skelett och en hel del funktionalitet, förbättrar vår produktivitet och underlättar utvecklingsprocessen. Tack för att du läser!