Wat gaat er in de “Controller” in “MVC”?

Ik denk dat ik de basisconcepten van MVC begrijp – het model bevat de gegevens en het gedrag van de applicatie, de weergave is verantwoordelijk voor het weergeven ervan aan de gebruiker en de controller behandelt gebruikersinvoer. Waar ik niet zeker van ben, is precies water in de controller gaat.

Laten we bijvoorbeeld zeggen dat ik een vrij eenvoudige toepassing heb (ik denk specifiek aan Java, maar ik veronderstel dat dezelfde principes elders gelden). Ik organiseer mijn code in 3 pakketten genaamd app.model, app.viewen app.controller.

Binnen het pakket app.modelheb ik een paar klassen die het daadwerkelijke gedrag van de applicatie weerspiegelen. Deze extends Observableen gebruiken setChanged()en notifyObservers()om de weergaven te activeren om indien nodig bij te werken.

Het app.view-pakket heeft een klasse (of meerdere klassen voor verschillende soorten weergave) die gebruikmaakt van javax.swing-componenten om de weergave af te handelen. Sommige van deze componenten moeten worden teruggekoppeld naar het model. Als ik het goed begrijp, zou de View niets te maken moeten hebben met de feedback – dat zou door de Controller moeten worden afgehandeld.

Dus wat stop ik eigenlijk in de Controller? Zet ik de public void actionPerformed(ActionEvent e)in de View met alleen een aanroep van een methode in de Controller? Zo ja, moet er een validatie enz. worden gedaan in de Controller? Zo ja, hoe kan ik foutmeldingen terugkoppelen naar de View – moet dat opnieuw door het model gaan of moet de controller het gewoon rechtstreeks terugsturen naar View?

Als de validatie wordt gedaan in de weergave, wat moet ik dan in de controller plaatsen?

Sorry voor de lange vraag, ik wilde gewoon mijn begrip van het proces documenteren en hopelijk kan iemand dit probleem voor mij ophelderen!


Antwoord 1, autoriteit 100%

In het door u voorgestelde voorbeeld heeft u gelijk: “de gebruiker heeft op de knop ‘dit item verwijderen’ geklikt” in de interface zou eigenlijk gewoon de “verwijder”-functie van de controller moeten oproepen. De controller heeft echter geen idee hoe de weergave eruitziet, en daarom moet uw weergave informatie verzamelen, zoals “op welk item is geklikt?”

In een gespreksformulier:

Bekijken: “Hé, controller, de gebruiker heeft me net verteld dat hij item 4 wil verwijderen.”
Controller: “Hmm, na zijn inloggegevens te hebben gecontroleerd, mag hij dat doen… Hé, model, ik wil dat je item 4 krijgt en alles doet wat je doet om het te verwijderen.”
Model: “Item 4… begrepen. Het is verwijderd. Terug naar jou, controller.”
Controller: “Hier, ik zal de nieuwe set gegevens verzamelen. Terug naar jou, bekijk.”
Bekijken: “Cool, ik laat de nieuwe set nu aan de gebruiker zien.”

Aan het einde van die sectie heb je een optie: ofwel kan de weergave een afzonderlijk verzoek doen, “geef me de meest recente dataset”, en dus zuiverder zijn, of de controller retourneert impliciet de nieuwe dataset met de bewerking “verwijderen”.


Antwoord 2, autoriteit 13%

Het probleem met MVCis dat mensen denken dat de view, de controller en het model zo onafhankelijk mogelijk van elkaar moeten zijn. Ze zien het niet – een view en een controller zijn vaak met elkaar verweven – zien het als M(VC).

De controller is het invoermechanisme van de gebruikersinterface, die vaak verstrikt raakt in de weergave, vooral bij GUI’s. Desalniettemin is het beeld output en de controller input. Een view kan vaak werken zonder een bijbehorende controller, maar een controller is meestal veel minder handig zonder een view. Gebruiksvriendelijke controllers gebruiken de weergave om de invoer van de gebruiker op een meer zinvolle, intuïtieve manier te interpreteren. Dit is wat het moeilijk maakt om het concept van de controller van het uitzicht te scheiden.

Denk aan een radiografisch bestuurbare robot op een detectieveld in een verzegelde doos als model.

Het model gaat over toestands- en toestandsovergangen zonder concept van output (weergave) of wat de toestandsovergangen triggert. Ik kan de positie van de robot op het veld bepalen en de robot weet hoe hij van positie moet veranderen (een stap vooruit/achteruit/links/rechts doen. Makkelijk voor te stellen zonder zicht of een controller, maar doet niets nuttigs

Denk aan een weergave zonder controller, b.v. iemand in een andere kamer op het netwerk in een andere kamer kijkt naar de robotpositie terwijl (x,y)-coördinaten door een scrollende console stromen. Deze weergave geeft alleen de staat van het model weer, maar deze man heeft geen controller. Nogmaals, het is gemakkelijk om je dit beeld voor te stellen zonder een controller.

Denk aan een controller zonder uitzicht, b.v. iemand opgesloten in een kast met de radiocontroller afgestemd op de frequentie van de robot. Deze controller verzendt invoer en veroorzaakt statusovergangen zonder enig idee van wat ze met het model doen (als er al iets is). Makkelijk voor te stellen, maar niet echt nuttig zonder enige vorm van feedback van het uitzicht.

De meest gebruiksvriendelijke gebruikersinterface coördineren de weergave met de controller om een ​​intuïtievere gebruikersinterface te bieden. Stel je bijvoorbeeld een weergave/controller voor met een aanraakscherm dat de huidige positie van de robot in 2D laat zien en waarmee de gebruiker het punt op het scherm kan aanraken dat zich net voor de robot bevindt. De controller heeft details over de weergave nodig, b.v. de positie en schaal van het kijkvenster en de pixelpositie van de aangeraakte plek ten opzichte van de pixelpositie van de robot op het scherm) om dit correct te interpreteren (in tegenstelling tot de man die met de radiocontroller in de kast opgesloten zat).

Heb ik je vraag al beantwoord? 🙂

De controller is alles dat invoer van de gebruiker nodig heeft en dat wordt gebruikt om het model naar de overgangsstatus te brengen. Probeer de view en controller gescheiden te houden, maar realiseer je dat ze vaak van elkaar afhankelijk zijn, dus het is oké als de grens ertussen vaag is, dat wil zeggen dat de view en controller als afzonderlijke pakketten niet zo netjes gescheiden zijn als je zou doen graag, maar dat is oké. Mogelijk moet u accepteren dat de controller niet netjes wordt gescheiden van het aanzicht, aangezien het aanzicht van het model is.

… moet enige validatie enz. zijn
gedaan in de controller? Zo ja, hoe?
Ik feedback foutmeldingen terug naar de
Bekijk – mocht dat door de . gaan
Model opnieuw, of moet de Controller
stuur het gewoon rechtstreeks terug naar Bekijken?

Als de validatie is gedaan in de weergave,
wat zet ik in de Controller?

Ik zeg dat een gekoppelde weergave en controller vrij moeten communiceren zonder door het model te gaan. De controller neemt de invoer van de gebruiker en moet de validatie uitvoeren (misschien met behulp van informatie uit het model en/of de weergave), maar als de validatie mislukt, moet de controller de gerelateerde weergave direct kunnen bijwerken (bijv. foutmelding).

De zuurtest hiervoor is om jezelf af te vragen of een onafhankelijke blik (dwz de man in de andere kamer die de robotpositie via het netwerk bekijkt) iets zou moeten zien als gevolg van de validatiefout van iemand anders (bijv. de man in de kast probeerde de robot te vertellen het veld te verlaten). Over het algemeen is het antwoord nee – de validatiefout verhinderde de statusovergang. Als er geen staatsovergang was (de robot bewoog niet), is het niet nodig om de andere meningen te vertellen. De man in de kast kreeg gewoon geen feedback dat hij een illegale overgang probeerde te veroorzaken (geen weergave – slechte gebruikersinterface), en niemand anders hoeft dat te weten.

Als de man met het touchscreen de robot van het veld probeerde te sturen, kreeg hij een aardig gebruiksvriendelijk bericht waarin hij vroeg de robot niet te doden door hem uit het detectieveld te sturen, maar nogmaals, niemand anders hoeft dit te weten .

Als andere weergaven welvan deze fouten op de hoogte moeten zijn, dan zegt u in feite dat de invoer van de gebruiker en eventuele resulterende fouten deel uitmaken van het modelen de hele zaak is een beetje ingewikkelder …


Antwoord 3, autoriteit 4%

Hier is een goed artikelover de basis van MVC.

Er staat …

Controller – De controller vertaalt
interacties met het zicht op
acties die door het model moeten worden uitgevoerd.

Met andere woorden, uw bedrijfslogica. De controller reageert op acties van de gebruiker in de weergave en reageert. U plaatst hier validatie en selecteert de juiste weergave als de validatie mislukt of slaagt (foutpagina, berichtenvenster, wat dan ook).

Er is nog een goed artikel op Fowler.


Antwoord 4, autoriteit 4%

Het MVC-patroon wil alleen dat u de presentatie scheidt(= weergave) van de bedrijfslogica(= model). Het controllergedeelte is er alleen om verwarring te zaaien.


Antwoord 5, autoriteit 2%

Praktisch gesproken heb ik het concept van de controller nooit bijzonder nuttig gevonden. Ik gebruik strikte model/view-scheiding in mijn code, maar er is geen duidelijk gedefinieerde controller. Het lijkt een onnodige abstractie.

Persoonlijk lijkt een volwaardige MVC het fabrieksontwerppatroon in die zin dat het gemakkelijk leidt tot verwarrend en te ingewikkeld ontwerp. Wees geen architectuurastronaut.


Antwoord 6, autoriteit 2%

Controller maakt echt deel uit van de weergave. Het is zijn taak om erachter te komen welke service(s) nodig zijn om aan het verzoek te voldoen, waarden uit de View te ontleden in objecten die de service-interface nodig heeft, de volgende View te bepalen en het antwoord terug te brengen in een vorm die de volgende View kan gebruiken . Het behandelt ook eventuele uitzonderingen die worden gegenereerd en geeft ze weer in Views die gebruikers kunnen begrijpen.

De servicelaag is het ding dat de use-cases, werkeenheden en modelobjecten kent. De controller zal voor elk type weergave anders zijn – je hebt niet dezelfde controller voor desktop-, browsergebaseerde, Flex- of mobiele gebruikersinterfaces. Dus ik zeg dat het echt deel uitmaakt van de gebruikersinterface.

Servicegericht: daar wordt het werk gedaan.


Antwoord 7, autoriteit 2%

Op basis van uw vraag krijg ik de indruk dat u een beetje vaag bent over de rol van het model. Het Model is gefixeerd op de gegevens die bij de aanvraag horen; als de app een database heeft, is het de taak van het model om ermee te praten. Het zal ook omgaan met alle eenvoudige logica die aan die gegevens is gekoppeld; als je een regel hebt die dat zegt voor alle gevallen waarin TABLE.foo == “Hoera!” en TABLE.bar == “Huzzah!” stel vervolgens TABLE.field=”W00t!” in, dan wilt u dat het model dit regelt.

De controller is wat het grootste deel van het gedrag van de applicatie zou moeten afhandelen. Dus om je vragen te beantwoorden:

Plaats ik de public void actionPerformed(ActionEvent e) in de View met alleen een aanroep van een methode in de Controller?

Ik zou nee zeggen. Ik zou zeggen dat dat in de Controller zou moeten leven; de View moet gewoon de gegevens die van de gebruikersinterface komen in de Controller invoeren en de Controller laten beslissen welke methoden als reactie moeten worden aangeroepen.

Zo ja, moet er een validatie etc worden gedaan in de Controller?

Het grootste deel van uw validatie zou eigenlijk door de controller moeten worden gedaan; het zou de vraag moeten beantwoorden of de gegevens geldig zijn, en als dat niet het geval is, voer dan de juiste foutmeldingen naar de View. In de praktijk kunt u enkele eenvoudige sanity-checks opnemen in de View-laag om de gebruikerservaring te verbeteren. (Ik denk in de eerste plaats aan webomgevingen, waar u misschien een foutmelding wilt hebben op het moment dat de gebruiker op “Verzenden” klikt in plaats van te wachten op het hele verzendproces -> laad de paginacyclus voordat u ze vertelt dat ze verpest.) Wees voorzichtig; je wilt niet meer moeite doen dan nodig is, en in veel omgevingen (nogmaals, ik denk aan het web) moet je gegevens die uit de gebruikersinterface komen vaak behandelen als een pak smerige smerige leugens totdat je hebt bevestigd dat het echt legitiem is.

Zo ja, hoe kan ik foutmeldingen terugkoppelen naar de View – moet dat opnieuw door het model gaan, of moet de controller het gewoon rechtstreeks terugsturen naar View?

Je zou een protocol moeten hebben waarbij de View niet per se weet wat er daarna gebeurt totdat de Controller dit vertelt. Welk scherm laat je ze zien nadat de gebruiker op die knop heeft gedrukt? De View weet het misschien niet, en de Controller weet het misschien ook niet totdat hij kijkt naar de gegevens die hij zojuist heeft gekregen. Dit kan zijn “Ga zoals verwacht naar dit andere scherm” of “Blijf op dit scherm en geef deze foutmelding weer”.

In mijn ervaring zou directe communicatie tussen het Model en de View zeer, zeer beperkt moeten zijn, en de View zou de gegevens van het Model niet direct moeten veranderen; dat zou de taak van de controller moeten zijn.

Als de validatie wordt gedaan in de weergave, wat moet ik dan in de controller plaatsen?

Zie hierboven; de echte validatie zou in de Controller moeten zijn. En hopelijk heb je nu enig idee wat er in de Controller moet komen te staan. 🙂

Het is vermeldenswaard dat het allemaal een beetje wazig kan worden aan de randen; zoals met bijna alles dat zo complex is als software-engineering, zullen er veel beoordelingen zijn. Gebruik gewoon je gezond verstand, probeer consistent te blijven binnen deze app en probeer de lessen die je leert toe te passen op het volgende project.


Antwoord 8

Hier is een vuistregel die ik gebruik: als het een procedure is die ik specifiekzal gebruiken voor een actie op dezepagina, hoort deze thuis in de controller , niet het model. Het model zou alleen een coherente abstractie van de gegevensopslag moeten bieden.

Ik ben op dit idee gekomen nadat ik met een grote webapp had gewerkt, geschreven door ontwikkelaars die dachten dat ze MVC begrepen, maar dat in werkelijkheid niet deden. Hun “controllers” zijn teruggebracht tot acht regels voor het aanroepen van statische klassenmethoden die gewoonlijk nergens anders worden genoemd :-/ waardoor hun modellen niet veel meer zijn dan manieren om naamruimten te creëren. Door dit op de juiste manier te refactoren, worden drie dingen gedaan: alle SQL wordt verplaatst naar de gegevenstoegangslaag (ook wel model genoemd), de controllercode wordt iets uitgebreider maar een stuk begrijpelijker, en de oude “model”-bestanden worden tot niets teruggebracht. 🙂


Antwoord 9

De controller is in de eerste plaats bedoeld voor de coördinatie tussen de weergave en het model.

Helaas wordt het soms vermengd met het uitzicht – in kleine apps is dit echter niet zo erg.

Ik stel voor dat je het volgende plaatst:

public void actionPerformed(ActionEvent e)

in de regelaar. Dan zou je actieluisteraar in jouw ogen moeten delegeren aan de controller.

Wat betreft het validatiegedeelte, je kunt het in de view of de controller plaatsen, ik denk persoonlijk dat het in de controller thuishoort.

Ik zou zeker aanraden om eens te kijken naar Passive View en Supervising Presenter (wat in wezen is waar Model View Presenter in is opgesplitst – in ieder geval door Fowler). Zie:

http://www.martinfowler.com/eaaDev/PassiveScreen.html

http://www.martinfowler.com/eaaDev/SupervisingPresenter.html


Antwoord 10

merk ook op dat elke Swing-widget de drie MVC-componenten kan bevatten: elk heeft een Model (dwz ButtonModel), een View (BasicButtonUI) en een Control (JButton zelf).


Antwoord 11

Je hebt in wezen gelijk over wat je in de controller stopt. Het is de enige manier waarop het Model moet interageren met de View. De uitgevoerde actie kan in de weergave worden geplaatst, maar de daadwerkelijke functionaliteit kan in een andere klasse worden geplaatst die als de controller zou fungeren. Als je dit gaat doen, raad ik aan om naar het commandopatroon te kijken, een manier om alle commando’s met dezelfde ontvanger te abstraheren. Sorry voor de uitweiding.

Hoe dan ook, een juiste MVC-implementatie heeft alleen de volgende interacties:
Model-> Visie
Bekijk -> Controller
Regelaar -> Bekijk

De enige plaats waar er nog een interactie kan zijn, is als u een waarnemer gebruikt om de weergave bij te werken, waarna de weergave de controller om de benodigde informatie moet vragen.


Antwoord 12

Zoals ik het begrijp, vertaalt de Controller van acties op gebruikersinterface naar acties op applicatieniveau. In een videogame kan de controller bijvoorbeeld “de muis zoveel pixels bewogen” vertalen in “wil in die en die richting kijken”. In een CRUD-app kan de vertaling “op die en die knop klikken” om “print dit ding”, maar het concept is hetzelfde.


Antwoord 13

We doen het op deze manier, waarbij we controllers voornamelijk gebruiken om gebruikersgestuurde invoer/acties af te handelen en erop te reageren (en _Logica voor al het andere, behalve weergave, gegevens en voor de hand liggende _Model-dingen):

(1) (reactie, reactie – wat de webapp “doet” als reactie op de gebruiker)
Blog_Controller

->main()

->handleSubmit_AddNewCustomer()

->verifyUser_HasProperAuth()

(2) (“zakelijke” logica, wat en hoe de webapp “denkt”)
Blog_Logic

->sanityCheck_AddNewCustomer()

->handleUsernameChange()

->sendEmail_NotifyRequestedUpdate()

(3) (views, portals, hoe de webapp “verschijnt”)
Blog_View

->genWelkom()

->genForm_AddNewBlogEntry()

->genPage_DataEntryForm()

(4) (alleen data-object, verkregen in _construct() van elke Blog*-klasse, gebruikt om alle webapp/inmemory-gegevens bij elkaar te houden als één object)
Blog_Meta

(5) (basisgegevenslaag, leest/schrijft naar DB’s)
Blog_Model

->saveDataToMemcache()

->saveDataToMongo()

->saveDataToSql()

->loadData()

Soms raken we een beetje in de war over waar we een methode moeten plaatsen, in de C of de L. Maar het model is ijzersterk, kristalhelder en aangezien alle gegevens in het geheugen zich in de _Meta bevinden, is het een goed idee daar ook. Onze grootste sprong voorwaarts was trouwens het overnemen van het _Meta-gebruik, omdat dit alle crud van de verschillende _C-, _L- en _Model-objecten opruimde, het allemaal mentaal gemakkelijk te beheren maakte, plus, in één klap, het gaf ons wat er wordt genaamd “Dependency Injection”, of een manier om een ​​hele omgeving samen met alle gegevens door te geven (waarvan de bonus het eenvoudig maken van een “test”-omgeving is).

Other episodes