De Model-View-Controller (MVC) architectuurpatroon is al lang een hoeksteen van gestructureerde webapplicatie ontwikkeling. Door het scheiden van een toepassing in drie onderling verbonden componenten .Model (data en bedrijfslogica), View (user interface), en Controller (input handling) .MVC bevordert georganiseerde code die gemakkelijker te handhaven, testen en uit te breiden is. Maar zelfs binnen deze duidelijke scheiding, ontwikkelaars vaak te maken met wrijving: de ruwe gegevens van het domeinmodel zelden past de exacte vorm vereist door het uitzicht, en presentatie logica neigt om te lekken in controllers of standpunten, waardoor rommelige, moeilijk te onderhouden code. Dit is waar het ViewModel patroon onmisbaar wordt. Een ViewModel fungeert als een op maat gemaakte tussenpersoon die data bindend en centraliseert presentatie logica, waardoor de MVC architectuur aan zijn belofte van schone scheiding en onderhoudable code te voldoen.

Wat is een ViewModel?

Een ViewModel is een aangepaste klasse die specifiek is ontworpen om te voldoen aan de gegevens en gedragsbehoeften van een bepaalde kijk. Het zit tussen het Model (de domein- of datatoegangslaag) en het Beeld, het omzetten van ruwe gegevens in een vorm die de weergave moeiteloos kan consumeren. In tegenstelling tot het domeinmodel, dat business entiteiten en regels vertegenwoordigt (bijvoorbeeld een object met , , , en ]), kan een ViewModel alleen de velden bevatten die nodig zijn voor dat uitzicht (een berekende eigenschap), , of een lijst van [[[FLT:]]. Het maakt ook complexe objectdiagrammen af om te voorkomen dat het uitzicht nodig is om relatieketens te navigeren.

Beschouw een typische gebruikersprofielpagina. Het domeinmodel zou kunnen hebben gescheiden en entiteiten. Een zou de gebruiker de naam, stad, en status in één enkele tekenreeks kunnen combineren en de join-datum in een menselijk leesbaar formaat presenteren. Zonder een ViewModel zou het uitzicht de structuur van beide entiteiten moeten begrijpen en een duidelijke schending van de scheiding van zorgen moeten uitvoeren.

ViewModel vs. Domeinmodel vs. DTO

Het is belangrijk om een ViewModel te onderscheiden van andere soortgelijke patronen. Een Data Transfer Object (DTO) wordt vaak gebruikt om gegevens te verplaatsen tussen lagen (bijvoorbeeld, van een dienst naar een controller) en meestal ontbreekt gedrag. Een ViewModel, aan de andere kant, is uitzicht-specifiek en kan presentatie logica, validatie attributen en state management (bijv., is de gebruiker in de bewerking modus?). In tegenstelling, het domein model bevat zakelijke regels en invarianten; je mag nooit bloot domeinmodellen direct aan weergaven, omdat dat koppelt uw UI aan uw zakelijke laag en kan leiden tot veiligheid en onderhoud problemen.

Hoe BeeldModels de gegevensbinding vereenvoudigen

Databinding is het mechanisme dat UI-elementen verbindt met gegevensbronnen, waarbij automatisch waarden worden gesynchroniseerd. In MVC-frames aan de server, zoals ASP.NET MVC, Spring MVC of Laravel, vindt de databinding meestal plaats tijdens formulierinzendingen: het kader leest HTTP-verzoekparameters en brengt ze in kaart met een modelobject. Wanneer dat object een ViewModel is, wordt de mapping eenvoudig en veilig.

Het gebruik van een ViewModel voor databinding biedt verschillende voordelen:

  • Precise mapping of form fields: U kunt precies bepalen welke velden de view verwacht, waarbij over-posting aanvallen worden vermeden waar een kwaadaardige gebruiker extra velden injecteert (bijvoorbeeld op een registratieformulier). ViewModels fungeren als een whitelist.
  • Sterk getypte validatieattributen: ViewModels staan u toe om validatieregels (zoals , , of aangepaste validatoren) direct op de eigenschappen die het weergavescherm geeft te plaatsen. Dit centraliseert validatielogica en maakt zowel client-side als server-side validatie naadloos mogelijk.
  • Verminderde bindingsfouten: Omdat de ViewModel één-op-één in kaart brengt met de UI-vorm, vermijden ontwikkelaars het giswerk van matching request parameters voor complexe objectgrafieken. Dit vermindert bindingsfouten en vermindert boilerplate code in controllers.

Voorbeeld: User Registration Form

Zonder ViewModel kan een controller een registratieaanvraag binden aan een domeinmodel met velden als en ] dat het formulier nooit mag worden ingesteld. Met een die alleen , , en ] kan de controller de ViewModel veilig binden, valideren en vervolgens in kaart brengen naar het domeinmodel binnen de bedrijfslogica. Hierdoor blijft de controller lean en het domeinmodel beschermd.

In client-side kaders die gebruik maken van twee-weg binding (bijv., Angular of Vue.js), ViewModels dienen een soortgelijke rol door het definiëren van de vorm van gegevens die componenten zullen weergeven en wijzigen. De ViewModel kan omvatten berekende eigenschappen, wijziging tracking, en event handlers, die allemaal zijn ingekapseld en testbaar.

Rol van BeeldModels in Presentatie Logica

De presentatie logica omvat alles wat de weergave nodig heeft om te doen met de gegevens: formatteren data, omzetten valuta, het concatenteren van namen, het berekenen van totalen, het bepalen van welke secties te tonen op basis van gebruikersrechten, en het beheren van UI-status (bijv., .Loading versus . .Error . Zonder ViewModels , deze logica eindigt vaak in het zicht (met behulp van helper functies of inline formattering) of in de controller (maakt het ontestbaar en opgeblazen). ViewModels centraliseren deze logica in een toegewijde, testbare klasse.

Bijvoorbeeld, een bestelgegevensweergave kan nodig zijn om te tonen:

  • Besteldatum in een vriendelijk formaat (
  • Volledige naam van de klant (gecombineerd met de eerste en laatste)
  • Artikel 4, lid 1, punt 114, van de VKV
  • Bestel totaal met belasting en verzending
  • Of de bestelling in aanmerking komt voor annulering (op basis van status en verstreken tijd)

Al deze transformaties horen in de ViewModel thuis. Het beeld geeft eenvoudigweg eigenschappen weer als , , (elk ] met een ), en . De controller creëert de ViewModel door het domeinmodel uit de servicelaag te halen, in kaart te brengen en het naar het uitzicht te brengen.

Gegevens uit meerdere bronnen samenvoegen

Een andere gemeenschappelijke behoefte is het weergeven van gegevens van meerdere domeinmodellen op één pagina. Een dashboard kan gebruikersprofielgegevens, recente bestellingen en meldingen combineren. Een ViewModel kan al deze stukken in één object houden, waardoor het gemakkelijk is om een samenhangende pagina te maken. De controller roept aparte diensten op en assembleert de ViewModel, die ervoor zorgt dat het uitzicht niet meerdere gegevensbronnen hoeft te begrijpen.

Voordelen van het gebruik van ViewModels

De voordelen van de consequent toepassing van het ViewModel patroon zijn substantieel en direct impact code kwaliteit, onderhoudbaarheid en team productiviteit.

Verbeterde scheiding van zorg

ViewModels handhaven een schone grens tussen de domeinlaag (zakenregels) en de presentatielaag. Wijzigingen aan de UI (zoals het toevoegen van een nieuw veld aan een formulier) vereisen alleen wijzigingen in de ViewModel en weergave, niet in het domeinmodel. Omgekeerd, veranderingen in het domeinmodel (zoals een nieuwe eigenschap op een entiteit) niet rimpelen aan het uitzicht tenzij u de ViewModel mapping bijwerken. Deze isolatie vermindert regressierisico.

Verbeterde testbaarheid van UI Logic

Presentatie logica in weergaven is berucht moeilijk te unit test. Met ViewModels, kunt u testen opmaak, aggregatie, en staat management in afzondering van de UI-frame. U kunt een eenheid testen die controleren of zonder het laden van een browser of renderen van HTML. Dit leidt tot snellere feedback en meer betrouwbare code.

Verlaagde codeduplicatie

Wanneer dezelfde gegevens in meerdere weergaven moeten worden weergegeven (bijvoorbeeld een productkaart in een lijst en in een detailpagina), kunt u een gemeenschappelijke ViewModel klasse maken die beide weergaven gebruiken. Presentatie logica leeft op één plaats in plaats van in elke weergave gekopieerd te worden. Dit maakt ook UX wijzigingen gemakkelijker te verspreiden.

Betere organisatie van presentatiespecifieke gegevens

ViewModels slaan UI-status zoals

Gemeenschappelijke valkuilen en beste praktijken

Zelfs met zijn voordelen, kan het ViewModel patroon verkeerd worden toegepast. Hier zijn veel voorkomende fouten en hoe ze te vermijden.

BeeldModels voor elke weergave overbelasten

Niet elke weergave heeft een aangepaste ViewModel nodig. Voor eenvoudige alleen-display pagina's die overeenkomen met een enkel domeinobject, die direct aan een DTO binden (of zelfs het domeinmodel als je een alleen-lezen laag gebruikt) kan aanvaardbaar zijn. De regel van duim: als je jezelf het toevoegen van formatteren of combineren van eigenschappen, het is tijd voor een ViewModel. Gebruik oordeel . Het creëren van een ViewModel voor elke kleine gedeeltelijke weergave kan opgeblazen de codebase.

Anemische weergaveModels

Een ViewModel die niets anders is dan een zak met openbare eigenschappen zonder gedrag kan leiden tot logica lekken elders. Inclusief helper methoden of berekende eigenschappen die presentatie logica inkapselen (bijv. ). Dit houdt logica in de ViewModel waar het hoort.

Naamgevingsverdragen

NaamweergaveModels om expliciet hun doel aan te geven. Gebruik achtervoegsels als (bv. ) of meer specifieke namen zoals als het wordt gebruikt voor formulierindiening. Vermijd generieke namen zoals ] die obscure intentie. Organiseer constant ViewModels in een aparte map (bv. in ASP.NET MVC) om de projectstructuur schoon te houden.

In kaart brengen tussen Domein en BeeldModel

Handmatige mapping (eigenschap per eigenschap) is vervelend en foutgevoelig. Gebruik een hulpmiddel zoals AutoMapper voor .NET, MapStruct voor Java, of helper functies in PHP om de mapping automatiseren. Echter, wees voorzichtig niet blind te map . Onverwijld de ViewModel structuur verschilt aanzienlijk van het domein, en handmatige mapping biedt helderheid. Automatiseer de eenvoudige mappings, maar aarzel niet om expliciete logica te schrijven voor complexe transformaties.

Tenuitvoerlegging van BeeldModels over verschillende kaders

De principes zijn universeel, maar implementaties verschillen enigszins. Laten we kijken naar drie populaire MVC-kaders.

ASP.NET MVC / Core

In ASP.NET MVC zijn ViewModels gewoon C#-klassen die in een -map worden geplaatst. Controllers ontvangen ze via actiemethodeparameters met behulp van attributen of weergavemodelbinding. Scheermesweergaven worden sterk getypt naar de ViewModel (). Het kader ondersteunt validatieattributen direct op ViewModel eigenschappen. ViewModels worden ook gebruikt voor het weergeven van gegevens; de controller geeft terug . Bijvoorbeeld:

public class UserProfileViewModel
{
 public int Id { get; set; }
 [Display(Name = "Full Name")]
 public string FullName { get; set; }
 public string Email { get; set; }
 [DataType(DataType.Date)]
 public DateTime JoinedDate { get; set; }
}

Meer informatie over ViewModels in ASP.NET Core uit De officiële documentatie van Microsoft.

Voorjaar MVC (Java)

In de lente MVC worden ViewModels vaak ..vorm backing objects .. of ..command objects genoemd. . . Ze zijn gewoon Java PoJO's met validatie annotaties (zoals , ). De controller gebruikt om vormgegevens te binden aan de ViewModel. Voor weergavedoeleinden kunt u gegevens in het model plaatsen via en vervolgens verwijzen in JSP of Thyleaf templates. Spring ondersteunt ook voor custom property editors.

Laravel (PHP)

Laravel heeft geen ingebouwde ViewModel klassen, maar moedigt het patroon door vormverzoeken (validatie) en resource classes (API antwoorden). Voor server-rendered views, kunt u aangepaste klassen te creëren of gewoon een array. Echter, met behulp van speciale ViewModel klassen (bijv., ) verbetert type veiligheid en testbaarheid. Laravel. templates kunnen een instantie ontvangen en toegang krijgen tot de methoden. Zie ]Laravels formulier aanvraag documentatie[] voor validatie scheiding.

Geavanceerde weergaveModelpatronen

Naarmate toepassingen groeien, kunt u meer geavanceerde ViewModel structuren nodig hebben.

Genest BeeldModels

Wanneer een weergave een lijst van items bevat, maak dan een ouder ViewModel met een collectie van kind ViewModels. Bijvoorbeeld, een kan bevatten en ]. Elk kind ViewModel heeft zijn eigen presentatie logica.

BekijkenModel Erfelijkheid en samenstelling

Als meerdere weergaven gemeenschappelijke eigenschappen delen (bijvoorbeeld een .page header .. sectie met gebruikersinformatie en menu items), kunt u een basis ViewModel klasse en uitbreiden. Als alternatief, gebruik compositie: omvatten een als een eigenschap. Samenstelling is vaak flexibeler en vermijdt diepe erfenis hiërarchieën.

BeeldModels met Asynchrone Initialisatie

Sommige ViewModels vereisen gegevens van async-oproepen (bijvoorbeeld externe API's). U kunt een fabrieksmethode of een speciale service creëren die de ViewModel asynchroon bouwt. De controller wacht op de fabriek en geeft het resultaat door aan het uitzicht. Dit houdt de controller synchron en testbaar terwijl het ViewModel asynchroon kan worden bevolkt.

Conclusie

ViewModels zijn een krachtige maar vaak onderbenut gereedschap in MVC-ontwikkeling. Door te dienen als een op maat gemaakte tussenpersoon tussen modellen en standpunten, vereenvoudigen ze data bindend, centraliseren presentatie logica, en handhaven een schone scheiding van de zorgen. Ze beschermen domeinmodellen tegen UI-specifieke veranderingen, verbeteren testbaarheid, verminderen duplicatie, en maken de codebase meer onderhoudbaar naarmate de toepassing evolueert. Of u nu een kleine interne tool of een grote onderneming toepassing, investeren tijd in het crafting doordachte ViewModels betaalt dividenden in codekwaliteit en de productiviteit van de ontwikkelaar.

Als u ViewModels implementeert, vergeet niet om ze lean maar expressief te houden, hefboomvalidatie attributen, en gebruik mapping tools. Vermijd de val van het maken van elke weergave afhankelijk van een ViewModel te maken, gebruik ze waar ze waarde toevoegen. De discipline van het ontwerpen van ViewModels zal uw begrip van de ware behoeften van uw UI scherpen en leiden tot schonere, robuustere MVC-toepassingen. Zie Martin Folter ..Microsoft MVC architectuur overzicht ] voor een uitgebreide weergave van het patroon in ASP.NET.