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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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!