Introduktion till MVC-arkitekturen

Den mest populära applikationsarkitekturen som alla programmerare känner till är MVC . MVC står för Model-View-Controller .

Detta är inte så mycket applikationsarkitekturen som applikationskomponenternas arkitektur, men vi kommer att återkomma till denna nyans senare. Vad är MVC?

MVC är ett schema för att separera applikationsdata och styrlogik i tre separata komponenter – modell, vy och styrenhet – så att varje komponent kan modifieras oberoende.

  • Modell (modell) tillhandahåller data och svarar på kontrollkommandon genom att ändra dess tillstånd.
  • Vyn ansvarar för att visa modelldata för användaren som svar på modelländringar.
  • Controllern (Controllern) tolkar användarens handlingar och meddelar modellen om behovet av ändringar.

Denna modell uppfanns redan 1978 (!) År. Ja, problem med korrekt mjukvaruarkitektur var aktuella för 50 år sedan. Så här beskrivs denna modell av diagrammet i originalet:

Introduktion till MVC-arkitekturen

Modellen tillhandahåller data och metoder för att arbeta med dem: frågor till databasen, kontroll av korrekthet. Modellen är oberoende av vyn (vet inte hur man renderar data) och kontrollanten (har inga interaktionspunkter för användaren), vilket ger tillgång till och hantering av data.

Modellen är byggd på ett sådant sätt att den svarar på förfrågningar genom att ändra dess tillstånd, och meddelandet om "observatörer" kan byggas in. Modellen kan, på grund av oberoendet från den visuella representationen, ha flera olika representationer för en "modell".

Vyn ansvarar för att hämta nödvändig data från modellen och skicka den till användaren. Vyn behandlar inte användarinmatning.

Styrenheten tillhandahåller "kommunikationen" mellan användaren och systemet. Styr och dirigerar data från användaren till systemet och vice versa. Använder en modell och en vy för att genomföra önskad åtgärd.

Det finns en viss svårighet med det faktum att denna modell har utvecklats lite under decennierna. Det vill säga namnet förblev detsamma, men syftet med delarna började förändras.

MVC-arkitektur på webben

Tanken bakom MVC-designmönstret är mycket enkel: vi måste tydligt separera ansvaret för olika beteenden i våra applikationer:

Modell— Databehandling och tillämpningslogik.

se— tillhandahålla data till användaren i alla format som stöds.

kontroller- behandla användarförfrågningar och anropa lämpliga resurser.

Ansökan är uppdelad i tre huvudkomponenter som var och en ansvarar för olika uppgifter. Låt oss ta en närmare titt på komponenterna i en klient-serverapplikation med hjälp av ett exempel.

Kontroller

Användaren klickar på olika element på sidan i webbläsaren, som ett resultat av vilket webbläsaren skickar olika HTTP-förfrågningar: GET, POST eller andra. Styrenheten kan inkludera webbläsaren och JS-koden som fungerar på sidan.

Styrenhetens huvudfunktion i det här fallet är att anropa metoder på de nödvändiga objekten, hantera åtkomst till resurser för att utföra uppgifter som specificeras av användaren. Vanligtvis anropar styrenheten lämplig modell för uppgiften och väljer lämplig vy.

Modell

Modell i vid bemärkelse är de data och regler som används för att arbeta med datan – tillsammans utgör de applikationens affärslogik. Att designa en applikation börjar alltid med att bygga modeller av de objekt den opererar på.

Låt oss säga att vi har en webbutik som säljer böcker, är en person då bara en applikationsanvändare eller också författare till en bok? Dessa viktiga frågor måste tas upp under modelldesign.

Vidare finns det uppsättningar regler: vad kan göras, vad kan inte göras, vilka datamängder är acceptabla och vilka inte. Kan en bok existera utan en författare? Och författaren utan böcker? Kan användarens födelsedatum vara år 300 och så vidare.

Modellen ger kontrollanten en bild av de data som användaren har begärt (meddelande, boksida, bilder etc.). Datamodellen kommer att vara densamma oavsett hur vi vill presentera den för användaren. Därför väljer vi vilken tillgänglig vy som helst för att visa data.

Modellen innehåller den viktigaste delen av vår applikationslogik , logiken som löser problemet vi har att göra med (forum, butik, bank, etc.). Styrenheten innehåller mestadels organisatorisk logik för själva applikationen (precis som din projektledare).

Se

View tillhandahåller olika sätt att representera data som tas emot från modellen. Det kan vara en mall som är fylld med data. Det kan finnas flera olika vyer och kontrollanten väljer vilken som är bäst för den aktuella situationen.

En webbapplikation består vanligtvis av en uppsättning kontroller, modeller och vyer. Styrenheten kan bara finnas på backend, men det kan också finnas en variant av flera kontroller, när dess logik är spridd över frontend också. Ett bra exempel på detta tillvägagångssätt är vilken mobilapplikation som helst.

MVC-exempel på webben

Låt oss säga att du behöver utveckla en webbutik som kommer att sälja böcker. Användaren kan utföra följande åtgärder: se böcker, registrera, köpa, lägga till artiklar i den aktuella beställningen, markera böcker han gillar och köpa dem.

Din ansökan bör ha en modell som ansvarar för all affärslogik. Du behöver också en styrenhet som kommer att bearbeta alla användaråtgärder och omvandla dem till metodanrop från affärslogik. En kontrollmetod kan dock anropa många olika modellmetoder.

Du behöver också uppsättningar vyer: en lista med böcker, information om en bok, en kundvagn, en lista med beställningar. Varje sida i en webbapplikation är faktiskt en separat vy som visar en viss aspekt av modellen för användaren.

Låt oss se vad som händer om en användare öppnar en lista med bokhandelsrekommenderade böcker för att se titlar. Hela sekvensen av åtgärder kan beskrivas i form av 6 steg:

MVC-exempel på webben

Steg:

  1. Användaren klickar på länken "rekommenderad" och webbläsaren skickar en förfrågan till t.ex. /books/recommendations.
  2. Styrenheten kontrollerar begäran : användaren måste vara inloggad. Eller så borde vi ha samlingar av böcker för icke-inloggade användare. Styrenheten ringer sedan upp modellen och ber den returnera listan över böcker som rekommenderas för användare N.
  3. Modellen kommer åt databasen, hämtar information om böcker därifrån: böcker som är populära just nu, böcker köpta av användaren, böcker köpta av hans vänner, böcker från hans önskelista. Baserat på dessa data bygger modellen en lista med 10 rekommenderade böcker och returnerar dem till styrenheten.
  4. Styrenheten får en lista med rekommenderade böcker och tittar på den. I detta skede fattar kontrollanten beslut! Om det finns få böcker eller om listan är helt tom, begär den en lista med böcker för en ologgad användare. Om det pågår en kampanj just nu kan kontrollanten lägga till reklamböcker till listan.
  5. Styrenheten bestämmer vilken sida som ska visas för användaren. Det kan vara en felsida, en sida med en lista med böcker, en sida som gratulerar till att användaren har blivit miljonte besökare.
  6. Servern ger klienten sidan ( vy ) som valts av kontrollenheten. Den fylls med nödvändiga uppgifter (användarnamn, lista över böcker) och går till klienten.
  7. Klienten tar emot sidan och visar den för användaren.

Vilka är fördelarna med detta tillvägagångssätt?

Den mest uppenbara fördelen som vi får av att använda MVC-konceptet är en tydlig åtskillnad mellan presentationslogik (användargränssnitt) och applikationslogik (backend).

Den andra fördelen är uppdelningen av serverdelen i två: en smart modell ( executor ) och en controller ( decision center ) .

I det föregående exemplet var det ett ögonblick då styrenheten kunde ta emot en tom lista med rekommenderade böcker från modellen och bestämma vad den skulle göra med den. Teoretiskt kan denna logik sättas in direkt i modellen.

För det första, när den begärde rekommenderade böcker, skulle modellen bestämma vad den ska göra om listan är tom. Då skulle jag behöva lägga till koden på samma ställe, vad ska jag göra om det är en kampanj på gång nu, sedan fler olika alternativ.

Sedan visade det sig att butiksadministratören ville se hur användarens sida skulle se ut utan kampanj, eller tvärtom, det finns ingen kampanj nu, men han vill se hur den framtida kampanjen kommer att visas. Och det finns inga metoder för detta. Därför beslutades det att separera beslutscentret (controllern) från affärslogiken (modellen).

Förutom att isolera vyer från applikationslogik, reducerar MVC-konceptet avsevärt komplexiteten hos stora applikationer. Koden är mycket mer strukturerad, vilket gör det lättare att underhålla, testa och återanvända lösningar.

När du förstår konceptet med MVC inser du som utvecklare var du behöver lägga till sortering av listan med böcker:

  • På databasfrågenivå.
  • På nivån för affärslogik (modell).
  • På affärslogiknivå (controller).
  • I vyn - på kundsidan.

Och detta är inte en retorisk fråga. Fundera just nu på var och varför du behöver lägga till koden för att sortera listan med böcker.

Klassisk MVC-modell

Interaktion mellan MVC-komponenter implementeras på olika sätt i webbapplikationer och mobilapplikationer. Det beror på att webbappen är kortlivad, behandlar en användarförfrågan och avslutar, medan mobilappen behandlar många förfrågningar utan att starta om.

Webbapplikationer använder vanligtvis den "passiva" modellen, medan mobilapplikationer använder den "aktiva" modellen. Den aktiva modellen, till skillnad från den passiva, låter dig prenumerera och få meddelanden om ändringar i den. Detta krävs inte för webbapplikationer.

Så här ser samspelet mellan komponenter i olika modeller ut:

Klassisk MVC-modell

Mobilapplikationer (aktiv modell) använder aktivt händelser och händelseprenumerationsmekanismen. Med detta tillvägagångssätt prenumererar view ( view ) på modelländringar. Sedan, när någon händelse inträffar (till exempel användaren klickar på en knapp), anropas styrenheten . Det ger också modellen ett kommando för att ändra data.

Om vissa data har ändrats genererar modellen en händelse om att ändra denna data. Alla vyer som har prenumererat på denna händelse (för vilka det är viktigt att ändra just denna data) får denna händelse och uppdaterar data i deras gränssnitt.

I webbapplikationer är saker organiserade lite annorlunda. Den huvudsakliga tekniska skillnaden är att klienten inte kan ta emot meddelanden på serversidan på initiativ av servern .

Därför skickar en kontroller i en webbapplikation vanligtvis inga meddelanden till vyn, utan ger klienten en ny sida, vilket tekniskt sett är en ny vy eller till och med en ny klientapplikation (om den ena sidan inte vet något om den andra) .

För närvarande är detta problem delvis löst med hjälp av följande tillvägagångssätt:

  • Fråga regelbundet servern efter ändringar av viktiga data (en gång i minuten eller mer).
  • WebSockets tillåter en klient att prenumerera på servermeddelanden.
  • Webb-push-meddelanden från serversidan.
  • HTTP/2-protokollet tillåter servern att initiera sändningen av meddelanden till klienten.