Model View Controller in Swift en Objective-C

Model View Controller

Eén van de conventies die je regelmatig tegenkomt als je serieus aan de slag gaat met het maken van apps, is MVC: Model View Controller. Met name als je er nog niet zoveel mee te maken hebt gehad, lijkt Model View Controller verwarrend. In de praktijk valt het echter enorm mee. Volgens de Model View Controller-conventie bestaat een app, of een gedeelte ervan, eigenlijk uit drie ‘onderdelen’:

  • Het model van de app: dit is het ‘brein’; het gedeelte waarin informatie wordt opgeslagen en opgehaald, waarin bewerkingen op die informatie worden uitgevoerd en waarin beslissingen worden genomen.
  • De view van de app: datgene dat de buitenwereld ziet en gebruikt om met de app te communiceren. Via de view toont de app dus informatie en heeft de gebruiker de mogelijkheid om informatie in te voeren en/of te wijzigen en om de app opdrachten te geven.
  • De controller van de app: de verbindende schakel tussen het model en de view. Als er in het model iets verandert (of als daar een beslissing wordt genomen), zorgt de controller ervoor dat de view wordt bijgewerkt. En omgekeerd: als de gebruiker iets met de view doet, bijvoorbeeld door op een button te tikken of tekst te wijzigen, zorgt de controller ervoor dat het model daarvan op de hoogte wordt gebracht.

Met die drie onderdelen hebben we alle drie de aspecten van MVC benoemd: Model, View en Controller.

Model View Controller: schaken

Een manier om MVC te demonstreren, is met behulp van een spelletje schaak. In de volgende afbeelding zie je dit gedemonstreerd.

Model view controller en het schaakspel

  • Het schaakbord is de view: het toont de positie van de schaakstukken en het geeft je de mogelijkheid om die stukken te verplaatsen.
  • Je hersenen zijn het model: je beoordeelt, aan de hand van je strategie en van de positie van de schaakstukken, wat de beste zet is.
  • Je handen en ogen vormen de controller: je gebruikt ze om schaakstukken te verplaatsen en om te kijken waar de schaakstukken staan.

‘Tussen’ het schaakbord en je hersenen staan dus je handen en ogen: je gebruikt ze om informatie van het schaakbord aan je hersenen door te geven en om, nadat je hersenen de optimale zet hebben bepaald, een schaakstuk te verplaatsen. Met andere woorden: de controller staat ‘tussen’ het model (waar de beslissingen worden genomen) en de view (waar de huidige stand van zaken wordt weergegeven).

Wie communiceert met wie?

Zoals je in de vorige afbeelding zag, loopt alles via de controller (de groene pijlen). Het model (je hersenen) en de view (het schaakbord) ‘praten’ niet rechtstreeks met elkaar (de rode ‘muur’ zit er tussen). Alle communicatie tussen het model en de view loopt dus via de controller. Precies dàt is het Model View Controller-principe: de view en het model hebben niets met elkaar te maken en weten niet eens van elkaars bestaan. De controller zorgt ervoor dat de juiste informatie uit de view aan het model wordt doorgegeven en andersom.

Hieronder zie je een uitgebreidere versie, waarin ook je tegenstander is opgenomen. Beide spelers hebben hun eigen model (hun brein) en hun eigen controller (hun ogen en handen). Het enige wat ze delen, is de view (het schaakbord).

Model View Controller

Model View Controller in de praktijk: apps

Ook in apps kun je het MVC-principe gebruiken. Sterker nog: op dat principe zijn goede apps altijd gebaseerd. Een schematische weergave van een eenvoudige Single View App die met MVC werkt, zie je in de volgende afbeelding.

Model view controller in apps

De gebruiker communiceert via de hoofd-view (en alle subviews): labels, buttons, sliders enzovoort. Zijn/haar ‘controller’ stuurt de informatie van de hoofd-view door naar zijn/haar hersenen (zijn/haar ‘model’) en andersom.

De app communiceert eveneens via de hoofd-view; de controller stuurt informatie van de hoofd-view door naar het model en andersom. Maar wat wellicht een beetje verwarrend is: in iOS apps worden controllers viewcontrollers genoemd. De reden hiervoor is de bijbehorende view, via een property (.view) aan de viewcontroller is gekoppeld.

Elke viewcontroller beschikt over een .view-property waarmee de bijbehorende hoofd-view, en alle eventuele subviews, kunnen worden benaderd.

MVC en de bestanden van een app

Hieronder zie je de bestanden van een app die strikt volgens het MVC-principe is gebouwd: Model.swift bevat de class voor het model van de app. ViewController.swift bevat de class voor de controller en een koppeling met de view: de view zelf is op Main.storyboard ontworpen.

De File Navigator van Xcode

Altijd een model-class – of niet?

Wanneer je het MVC-principe strikt hanteert, zul je altijd een model-class maken (wellicht met een andere naam, die duidelijk aangeeft wat het model doet). Ook apps met meer dan één model-classes bestaan uiteraard.

In de praktijk loopt het echter niet altijd zo’n vaart. Met name bij eenvoudige apps zetten ontwikkelaars vaak alle programmacode in één Swift-bestand: ViewController.swift. Het voordeel daarvan: je hebt al je code op één plek en je hoeft niet voortdurend heen en weer te schakelen tussen verschillende Swift-bestanden. Er is echter ook een nadeel: je kunt een viewcontroller met bijbehorende view heel moeilijk meenemen naar andere apps. Immers, zodra je een view met bijbehorende viewcontroller ook in een andere app wilt gebruiken, moet je er een kopie van maken en vervolgens overbodige code verwijderen: code die eigenlijk in het model thuishoort.

Eén van de voordelen van MVC is dat views en code heel overdraagbaar worden: je kunt gedeelten uit de ene app heel eenvoudig kopiëren naar een andere app. Vandaar dat het in een ‘productie-omgeving’ (dus als je niet aan het leren bent hoe iets werkt, of met een bepaald framework experimenteert), altijd de voorkeur heeft om model-code te scheiden van view- en viewcontroller-code. Hoe beter je dat doet, des te ‘generieker’ je views en viewcontrollers zullen zijn en des te gemakkelijker je ze kunt ‘meenemen’ naar een andere app. Je creëert dan als het ware een verzameling bouwstenen, waardoor het steeds eenvoudiger wordt om apps te ontwikkelen. Immers, die ene viewcontroller die je gebruikt voor app-instellingen, kun je dan probleemloos overnemen in alle apps die je ontwikkelt!

Voorbeelden zonder MVC

Zelf werk ik, met name tijdens demo’s, workshops en dergelijke, regelmatig met slechts één bestand: ViewController.swift, waarin ik vervolgens ook wat code zet die eigenlijk in een aparte model-class zou moeten staan. De reden: ik kan op die manier sneller iets uitleggen of demonstreren. Vandaar dat je in mijn boeken en video’s ook regelmatig voorbeelden tegenkomt waarin model-code niet per definitie is gescheiden van view-code en waarin de rollen model, view en controller en model niet altijd even duidelijk van elkaar zijn gescheiden.

Als je nog wel wat meer informatie over MVC kunt gebruiken, kun je online terecht bij een (Nederlandstalige) video erover. Ik behandel MVC regelmatig tijdens webinars. Klik hier voor een Webinar-video waarin MVC uitgebreid aan de orde komt.