VIPER-designmønster i Swift til iOS-applikationsudvikling.

Alt, hvad der har en begyndelse, har en ende -Gautama Buddha. Billedkilde: Screenshot taget fra filmen “The Matrix Revolutions”

Designmønstre er Guds gave til softwareudviklere. Dette er teknikker, der minimerer kodeduplicering, forhindrer høj kobling og standardiserer en almindelig måde at skrive kode på, der giver en generel løsning til gentagne situationer, mens du udvikler en software. I denne historie vil vi blive fortrolige med et designmønster kaldet VIPER (View, Interactor, Presenter, Entity and Router.) Til iOS-udvikling.

Forudsætninger: Før du begynder med VIPER, skal du sørge for at vide om arkitektonisk designmønster og delegationsmønster.

Hvad er Viper?

Viper er et designmønster, der implementerer 'adskillelse af bekymring' -paradigme. Oftest som MVP eller MVC følger det en modulær tilgang. En funktion, et modul. For hvert modul har VIPER fem (undertiden fire) forskellige klasser med forskellige roller. Ingen klasse går ud over dets eneste formål. Disse klasser følger.

Vis: Klasse, der har al koden, der viser appgrænsefladen til brugeren og får deres svar. Når du modtager et svar, får Se advarsler for præsentanten.

Presentator: Nucleus af et modul. Det får brugersvar fra visningen og fungerer i overensstemmelse hermed. Kun klasse for at kommunikere med alle de andre komponenter. Opkald til routeren til trådramming, Interactor til at hente data (netværksopkald eller lokale datakald), se for at opdatere brugergrænsefladen.

Interaktor: Har forretningsapplikationer for en app. Foretag primært API-opkald for at hente data fra en kilde. Ansvarlig for opkald af data, men ikke nødvendigvis fra sig selv.

Router: Gør trådrammen. Lytter fra programlederen om, hvilken skærm der skal præsenteres og udføres.

Enhed: Indeholder almindelige modelklasser, der bruges af interaktoren.

Nedenfor viser et simpelt diagram over VIPER

Viper Arkitektur

Viper med eksempel

Jeg har oprettet et simpelt projekt til at forklare huggorm. Det kan findes på GitHub. Det er en meget grundlæggende applikation, der viser en nyhedsoverskrift hentet fra en ekstern API. (hvor ubrugelig: p).

Viper er en delegationsdrevet arkitektur. Så det meste af kommunikationen mellem forskellige lag udføres gennem delegering. Et lag ringer til et andet gennem en protokol. Opkaldslag kalder en funktion fra en protokol. Lyttelaget er i overensstemmelse med den protokol og implementerer funktionen.

Nedenfor forklarer jeg, hvordan jeg har implementeret VIPER i et af mine prøveprojekter. Jeg foreslår, at du åbner projektet i github og går igennem det, mens du læser forklaringen.

protokoller

Jeg har oprettet en separat fil til alle protokoller.

En navnekonvention følges for at navngive en protokol. F.eks. 'ViewToPresenterProtocol'. Så det er en 'protokol', der bliver implementeret af 'præsenteren' for at lytte til, hvad 'visningen' har at sige.

  • PresenterToViewProtocol: Præsentator opkald, Vis lytter. Presentator modtager en henvisning fra denne protokol til adgang til visning. Visning er i overensstemmelse med protokollen.
  • ViewToPresenterProtocol: Se opkald, Presenter lytter.
  • InteractorToPresenterProtocol: Interactor-opkald, Præsentanten lytter.
  • PresentorToInteractorProtocol: Præsentant opkald, Interactor lytter.
  • PresenterToRouterProtocol: Præsentant opkald, router lytter.

App-flow

Vis har en henvisning til 'ViewToPresenterProtocol' for at få adgang til 'Presenter' og er i overensstemmelse med 'PresenterToViewProtocol'. I dets viewDidLoad () kalder det protokollens funktionsopdateringsvisning ().

//Udsigt
var presenter: ViewToPresenterProtocol?
tilsidesætte func viewDidLoad () {
   super.viewDidLoad ()
   studievært? .updateView ()
}

Presentator på den anden side er i overensstemmelse med 'ViewToPresenterProtocol'. Så det implementerer funktionen updateView ().

// Presenter
var interactor: PresentorToInteractorProtocol ?;
func updateView () {
   interaktor-? .fetchLiveNews ()
}

Inde i updateView () -lederen fortæller interaktoren at hente nogle live nyhedsdata.

Interactor er i overensstemmelse med 'PresentorToInteractorProtocol'. Så det implementerer fetchLiveNews () -funktionen. Denne funktion forsøger at foretage et netværksopkald og hente data. Det har en henvisning fra 'InteractorToPresenterProtocol' for at få adgang til 'Præsenteren'.

// interaktions
var programleder: InteractorToPresenterProtocol?

Hvis netværksopkaldet har hentet dataene, kaldes det følgende funktion.

// interaktions
self.presenter? .liveNewsFetched (nyheder: (arrayobjekt? [0])!)

hvis ikke

// interaktions
self.presenter? .liveNewsFetchedFailed ()

Nu er programleder også i overensstemmelse med 'InteractorToPresenterProtocol'. Så det implementerer disse funktioner.

// studievært
func liveNewsFetched (nyheder: LiveNewsModel) {
        visning?. showNews (nyheder: nyheder);
}
func liveNewsFetchedFailed () {
        visning? .showError ()
}

Så det fortæller visningen, om der skal vises nyheder eller for at vise fejlen.

Nu er View i overensstemmelse med 'PresenterToViewProtocol'. Således implementerer det showNews () og showError (). I disse to funktioner oversigter visningen visningen med de hentede data eller fejlen.

Enhedslaget

Ovenfor i appflowsektionen diskuteres entitetslag ikke. Det er ikke direkte forbundet med app-flowet. Men det er en integreret del for interaktoren. Enhedslag giver en model, som interaktor bruger til at oprette objekter fra de hentede data.

Router

Router sørger for trådrammen af ​​en applikation. Det er en meget grundlæggende ting at skifte skærm i en applikation. I VIPER er Router-laget ansvarlig for at udføre det.

Vi har diskuteret tidligere, at i VIPER-arkitektur har hver enkelt funktionalitet et enkelt modul, og et modul indeholder disse fem lag. En præsentant ringer til routeren for at oprette et nyt modul. Derefter starter routeren først alle lagklasser og returnerer modulet.

I mit prøveprojekt ændres der ikke noget in-app-modul. Men routing sker, når appen første gang lanceres. Så inden for AppDelegates 'didFinishLaunchingWithOptions ()' kaldes routerens createModule () -funktion. Det returnerer et modul. UIWindow-klassen viser derefter visningen af ​​dette modul.

Hvorfor og hvornår man skal bruge VIPER

VIPER følger en meget ren arkitektur. Det isolerer hvert modul fra andre. Så det er meget let at ændre eller rette bugs, da du kun skal opdatere et specifikt modul. Også for at have modulær tilgang skaber VIPER et meget godt miljø til enhedsprøvning. Da hvert modul er uafhængigt af andre, opretholder det lav kobling meget godt. Så opdelingen af ​​arbejdet mellem medudviklere er ret enkel.

VIPER skal bruges, når en applikations krav er meget veludformet. Arbejde med konstant skiftende krav kan skabe forvirring og messed up koder. Så det bør ikke bruges i et lille projekt, da MVP eller MVC vil være tilstrækkelige. VIPER skal også bruges, hvis alle udvikleren af ​​projektet fuldt ud forstår mønsteret.

VIPER-værktøjer

Hvis man ønsker at bruge VIPER i et projekt, ville det smarteste være at bruge en automatisk modulstrukturgenerator. Ellers vil det være ensformigt at oprette filer til moduler. Der er få generatorer tilgængelige online.

  • Generamba
  • VIPER-kode
  • VIPER Gen

Konklusion

Ligesom ethvert andet designmønster er VIPER selvforklarende. Man skal få sine hænder beskidte for at forstå hele billedet. Mit råd vil være først at starte med at oprette en meget grundlæggende app med VIPER og i processen læse online-ressource. Min github-repo kunne også være en god reference.

Glad kodning :)

Længe leve hellig Bangladesh.

Bangladesh er en verden af ​​metafor, af højt og lavt teater, med stor poesi og musik. Du taler med en risbonde, og du finder en digter. Du bliver kjent med en fejemaskine i gaderne, og du finder en bemærkelsesværdig sanger.
Jean Houston

Reference:

  1. https://medium.com/ios-os-x-development/ios-architecture-patterns-ecba4c38de52
  2. https://medium.com/@ankoma22/the-good-the-bad-and-the-ugly-of-viper-architecture-for-ios-apps-7272001b5347
  3. https://github.com/MindorksOpenSource/iOS-Viper-Architecture/tree/master/iOS-Viper-Architecture
  4. https://sourcemaking.com/design_patterns