Hvorfor MVC kanskje ikke være det beste mønsteret for kakaoapplikasjoner

MVC står for Model-View-Controller, og det er et utbredt arkitektonisk mønster for programvareutvikling. Det er de facto designmønsteret for kakaoutvikling, og det har vært i mange, mange år. De fleste av oss kan ikke forestille seg å bygge applikasjoner uten det. Både UIKit (iOS) og AppKit(macOS) gjør hyppig bruk av MVC. Det virker nesten som om vi ikke har et annet alternativ til å bygge programmer for iOS, tvOS, macOS og watchOS.

Selv om du ikke er kjent med modell-View-Controller-mønsteret, må du lære hvordan visninger (iOS) og Windows (MacOS) er relatert til kontroller modell spiller i en typisk kakao applikasjon. Heldigvis er MVC lett å lære.

I denne korte serien forklarer jeg hva MVC er, hvordan det ser ut i en typisk kakaoapplikasjon, og hvorfor det kanskje ikke er den beste løsningen for kakaoutviklere.

1. Et eksempel

La meg vise deg hvordan MVC-mønsteret ser ut i en typisk kakao-applikasjon. Eksemplet jeg skal vise deg fokuserer på iOS, men alt vi diskuterer gjelder også tvOS, macOS og watchOS. Åpne Xcode og opprett en ny iOS prosjekt basert på Enkeltvisningsprogram mal.

Gi navnet navnet på prosjektet MVC, og sett Språk til Fort og enheter til iPhone. Jeg bruker Xcode 8 for denne opplæringen. Prosjektets konfigurasjonsalternativer kan se litt annerledes ut hvis du bruker Xcode 9.

Som navnet antyder, definerer modell-View-Controller-mønsteret tre komponenter, modell, de utsikt, og kontrolleren. La meg vise deg hvor du kan finne disse komponentene i et typisk iOS-prosjekt.

Controllers

Kontrollerne av et iOS-program er visningskontrollere, forekomster av UIViewController klasse eller en underklasse derav. De UIViewController klassen er definert i UIKit rammeverk. Fordi vi valgte Enkeltvisningsprogram mal når vi satte opp prosjektet, skapte Xcode en kontroller for oss til å begynne med, ViewController klasse, definert i ViewController.Swift. Det arver fra UIViewController klasse.

Som navnet antyder, a UIViewController eksempel er ansvarlig for å kontrollere en visning, en forekomst av UIView klasse. Hver visningskontroller i et iOS-prosjekt holder en sterk referanse til en visning, en annen komponent i modell-View-Controller-mønsteret. De UIView klassen er også definert i UIKit rammeverk.

Visninger

Vi kan finne visningskomponenten i prosjektets hovedhistorieplate. Åpen Main.storyboard i Prosjektnavigator til venstre og inspisere Se kontroller scene. Scenen inneholder en visningskontroller, en forekomst av ViewController klasse, og det styrer a UIView forekomst.

Å velge Utsikt i storyboardet til venstre og åpne Identitetsinspektør til høyre. De Klasse feltet av visningen er satt til UIView. I et iOS-program er visninger vanligvis forekomster av UIKit UIView klasse eller en underklasse derav.

modeller

Så langt har vi utforsket kontrollerlaget og visningslaget. Men hvor kan vi finne modelllaget av prosjektet? Modellen er nesten alltid spesifikk for prosjektet du jobber med, og det er opp til deg å definere, implementere og bruke modell av prosjektet. jeg skriver modell, men du har vanligvis flere modeller, avhengig av prosjektets kompleksitet.

La oss legge til det siste stykket av MVC-puslespillet ved å lage en modell. Opprett en ny Swift-fil og gi den navnet Person.swift.

Å velge Person.swift i Prosjektnavigator til venstre og definere en struktur som heter Person. Vi definerer tre egenskaper: 

  • fornavn av type string
  • etternavn av type string
  • alder av type int
struct Person la firstName: String la lastName: String let age: Int

Du har nå en modell du kan bruke i prosjektet. La oss holde det enkelt og definere en eiendom, person, av type Person? i ViewController klasse. Vi lager en Person forekomst i visningsregulatorens viewDidLoad () metode og tilordne den til person eiendom.

importere UIKit klasse ViewController: UIViewController // MARK: - Egenskaper var person: Person? // MARK: - Se livscyklus overstyring func viewDidLoad () super.viewDidLoad () // Opprett person person = Person (fornavn: "John", etternavn: "Doe", alder: 40)

Det vi ser i dette eksemplet, er svært vanlig i kakao-applikasjoner drevet av modell-visning-kontroller-mønsteret. Visningskontrolleren eier og styrer modellen, og den bruker modellen til å fylle sin visning. I en mer kompleks applikasjon laster du modellens data fra en vedvarende butikk eller henter den fra en ekstern bakside.

La oss definere et uttak for a UILabel forekomst i visningsregulatoren og i hovedfortegnelsen, legg til en etikett til Se kontroller scene.

importere UIKit klasse ViewController: UIViewController // MARK: - Egenskaper @IBOutlet var etikett: UILabel! ...

I visningsregulatorens viewDidLoad () Metode, vi pakker ut verdien som er lagret i person eiendom og bruk dataene til å angi tekst eiendom av UILabel forekomst.

overstyr func viewDidLoad () super.viewDidLoad () // Opprett person person = Person (fornavn: "John", etternavn: "Doe", alder: 40) // Populere etikett hvis la person = person label.text = " \ (person.lastName), \ (person.firstName) (\ (person.age)) "

Resultatet er ikke veldig overraskende hvis du er kjent med kakaoutvikling. Dette er hva vi ender med.

2. Hva er Model View-Controller?

Modell-View-Controller-mønsteret er lett å forstå og plukke opp. Til tross for sin enkelhet, kan du finne et bredt spekter av smaker av MVC-mønsteret. MVC tilbyr bare en grunnleggende tegning som kan endres til plattformen den brukes på. 

Modell-View-Controller-mønsteret du er kjent med på iOS, tvOS, macOS og watchOS, er forskjellig på subtile måter fra den opprinnelige definisjonen. Mens forskjellene i forhold til den opprinnelige definisjonen er subtile, har de en betydelig innvirkning på koden du skriver, samt om vedlikeholdet av prosjektet.

Småprat

Modell-View-Controller-mønsteret er et gammelt designmønster. Det gjorde sitt første utseende på 1970-tallet i Smalltalk. Mønsteret ble oppfattet av Trygve Reenskaug. Gjennom årene har Model-View-Controller-mønsteret kommet seg inn i mange språk og rammer, inkludert Java, Rails og Django..

Jeg nevnte tidligere at MVC-mønsteret bryter programmene opp i tre forskjellige komponenter: modell, utsikt, og kontrolleren. Den opprinnelige implementeringen av mønsteret definerer at visningen er ansvarlig for visning av modellens data til brukeren. Brukeren samhandler med programmet gjennom visningslaget. Kontrolleren har ansvaret for å håndtere brukerinteraksjon og manipulerer modellens data som et resultat. Visningen visualiserer disse endringene til brukeren. Som illustrert i diagrammet nedenfor, spiller modellen en nøkkelrolle i MVC-mønsteret, slik det ble designet av Reenskaug.

MVC og kakao

Implementeringen vi bruker i kakaoutvikling, er forskjellig fra Reenskaugs originale design. Ta en titt på diagrammet nedenfor for å bedre forstå hva disse forskjellene innebærer.

Som nevnt tidligere, har visningen og kontrolleren et nært forhold. I et typisk iOS-program har en kontroller en sterk referanse til visningen det styrer. Visningen er en dum gjenstand som vet hvordan du viser data og svarer på brukerinteraksjon. Resultatet er en svært gjenbrukbar komponent.

Kontrolleren spiller en viktig rolle i kakao applikasjoner drevet av modell-View-Controller mønster. Det tar over noen av modellens oppgaver i Reenskaugs originale MVC-implementering. Utsikten og modellen kommuniserer ikke direkte med hverandre. I stedet er modellen vanligvis eid av kontrolleren, som den bruker til å konfigurere og fylle ut visningen den forvalter.

Jeg håper du kan se de subtile forskjellene mellom Reenskaugs opprinnelige implementering i Smalltalk og Kakaosimplementasjonen vi har blitt vant til. Forskjellene er små, men som jeg skal diskutere i et øyeblikk, er virkningen de har, viktig.

3. Det gode: Separasjon av bekymringer og gjenbruk

Før vi tar en titt på problemene MVC introduserer, vil jeg gjerne vise deg hvorfor modell-View-Controller-mønsteret har blitt et så populært og utbredt mønster i programvareutvikling. Modell-View-Controller-mønsteret vi bruker i kakaoutvikling har en rekke klare fordeler det arvet fra Reenskaugs opprinnelige implementering.

Den mest åpenbare fordelen med modell-View-Controller-mønsteret er a adskillelse av bekymringer. Visningslaget, for eksempel, er ansvarlig for å presentere data til brukeren. Modellen og kontrolleren lagene er ikke opptatt av data presentasjon. Men hvis du har brukt MVC i et kakao-prosjekt, vet du at dette ikke alltid er sant. Jeg snakker mer om det om et øyeblikk.

En direkte fordel med denne separasjonen av bekymringer er gjenbruk. Hver av komponentene i Model-View-Controller-mønsteret er fokusert på en bestemt oppgave, noe som betyr at byggeklossene i en MVC-applikasjon ofte er enkle å gjenbruke. Det tillater også at disse komponentene løsnes løst, og øker gjenbrukbarheten. Dette gjelder imidlertid ikke for hver komponent. I et kakao-prosjekt, for eksempel, er kontrollører ofte spesifikke for søknaden og ikke gode kandidater for gjenbruk.

Utsikten og modellene til et prosjekt er imidlertid svært gjenbrukbare dersom de er utformet riktig. Tabell- og samlingsvisninger, for eksempel, er UIView underklasser som brukes i millioner av applikasjoner. Fordi en tabellvisning delegerer brukerinteraksjon til et annet objekt og spør en datakilde for dataene den trenger å vise, kan den fokusere utelukkende på datapresentasjon og brukerinteraksjon.

4. Dårlige: Massive visningskontrollere

De fleste utviklere forstår raskt hva modell-View-Controller-mønsteret bringer til bordet og hvordan det skal implementeres. Dessverre har modell-View-Controller-mønsteret også en stygg side. Jeg skrev allerede om gjenbrukbarhet og separasjon av bekymringer. Jeg er sikker på at jeg ikke trenger å overbevise deg om disse fordelene. En tabellvisning er svært gjenbrukbar og utrolig effektiv. Utviklere kan bruke standard UIKit-komponenter i deres applikasjoner uten behov for underklasse eller tilpasning.

Hitting Limits of MVC

Men det er bare en del av historien. Du vet når du begynner å ramme grensene for MVC når massive visningskontrollere har smittet inn i prosjektet ditt. Det er på tide for endring når du pløyer gjennom hundrevis eller tusenvis av kodelinjer for å finne den ene metoden du leter etter. 

Dumping den i kontrolleren

De fleste utviklere vet hva som går inn i visningen og modelllagene av en typisk kakao-applikasjon drevet av modell-View-Controller-mønsteret. Men hvilken komponent er ansvarlig for formatering av dataene som vises til brukeren? Husk at visningene skal være dumme og gjenbrukbare. Visningen skal ikke formatere data. Ikke sant? Det bør bare vite hvordan å presentere data og svare på brukerinteraksjon. Skal modellen være opptatt av dataformatering?

Og hva med nettverk? Det er absolutt ikke oppgaven med visningen. Skal det bli delegert til modellen? Det høres ikke riktig. Hvorfor slipper vi det stykke kode inn i kontrolleren. Det føles ikke riktig, men det vil gjøre for nå.

Etter mange linjer med kode slutter du med en kontroller som er klar til å sprekke og et mareritt å teste. Testing? Jeg hører deg. Jeg ønsker ikke å teste en visningskontroller som lider av massiv visningskontrollersyndrom enten.

5. En bedre løsning

Du startet med gode intensjoner, men du endte med et prosjekt som har en samling av overvektige kontrollere som er vanskelig å administrere og vedlikeholde. Du gleder deg ikke til å legge til nye funksjoner i prosjektet du jobber med, fordi du åpner opp disse visningskontrollene, gjør deg syk i magen din. Lyder dette kjent?

Det er viktig å innse at dette er et vanlig scenario. Mange utviklere rammet grensene til modell-View-Controller-mønsteret og innser at de trenger noe bedre. Sjansen er at du allerede har sett på flere alternativer, for eksempel MVP (Model-View-Presenter) eller MVVM (Model-View-ViewModel).

I neste avdeling av denne serien, vil jeg zoome inn på Model-View-ViewModel mønster. Det vil føle seg merkelig kjent hvis du allerede har jobbet med Model-View-Controller-mønsteret. Men modell-View-ViewModel-mønsteret gir noen forbedringer til bordet som fungerer veldig bra for kakaoutvikling.

Og mens du venter, sjekk ut noen av våre andre innlegg på Cocoa app utvikling!