Uzorak dizajna spremišta u Swiftu

Čist način ispitivanja vaših modela

Koji problem rješava?

Ako trebate iznova i iznova ispitivati ​​predmete svog modela s različitih lokacija u vašem kodu, spremište može biti od velike pomoći pružiti jedinstvenu točku za rad s vašim modelima i ukloniti duplikat kôda upita. Možete ga uzeti još više i koristiti ga s protokolima. Na ovaj način možete jednostavno isključiti implementacije (na primjer za jedinice jedinice) ili možete ih upotrebljavati s generičkim uređajima za izradu više * bubnja rolne * generičke apstrakcije. U ovom ću članku pokriti sve ove slučajeve.

Skiciranje scene.

Recimo da imate neki kôd koji dohvaća podatke s API-ja i preslikava ih u modeliranje objekata. U ovom primjeru dohvatit ću popis članaka s poslužitelja.

To može izgledati pomalo funky, ali to je samo RxSwift, koristeći Moya kao sloj apstrakcije umrežavanja, ali to zapravo i nije važno da biste shvatili što se događa. O vama ovisi način na koji ćete dohvatiti svoje podatke.

Ovaj se dio koda čini

  1. GET zahtjev prema poslužitelju
  2. Mape vraćenog JSON-a u niz predmeta
  3. Zatvaranje se zove kada se obavi sav posao.

Zašto nam treba spremište?

U ovom trenutku nemamo. Ako API zovete samo jednom u cjelokupnoj bazi koda, dodavanje spremišta može biti pretjerano (ili kao što neki mogu reći prekomjerni inženjering).

Ok ... ali kada je objekt spremišta prikladan za upotrebu?
Recimo da baza koda počinje rasti i morate pisati kôd da biste dohvaćali članke iznova i iznova. Mogli biste reći „kopirajte kod i zalijepite ga gdje god trebate da biste preuzeli sve članke.“

Ništa nije učinjeno, nitko nije umro. Pravo?

U tom bi trenutku u vašem mozgu trebao početi treptati veliki crveni alarm.

Pozdrav spremištu.

Repozitorij je samo objekt koji objedinjuje sav kôd da biste na jednom mjestu pitali vaše modele, tako da imate unos s jednom točkom ako želite npr. nabavite sve članke.

Napravimo objekt spremišta koji pruža javni API za dobivanje članaka.

Sada možemo nazvati ovu metodu i ne moramo se brinuti o onome što se događa iza scene kako bismo dobili stvarne članke.
Samo nazovite metodu i dobićete članke. Lijepo, zar ne?
Ali čekaj, ima još!

Bavite se svim interakcijama članaka

Spremište možemo koristiti kako bismo dodali više metoda za interakciju s našim objektom modela. Najčešće želite raditi CRUD (kreirati, čitati, ažurirati, brisati) operacije na vašem modelu. Pa, samo dodajte logiku za te operacije u spremištu.

Ovo čini lijep API koji se koristi u cijelom kodu, a da ne morate ponavljati isti kod iznova i iznova.

U praksi bi upotreba spremišta izgledala ovako.

Prilično lijepo i čitljivo, zar ne? Ali, pričekajte da postane još bolje.

Pojačanje: protokoli

U prethodnom kôdu uvijek sam koristio primjer "dobivanja podataka iz API-ja". Ali što ako trebate dodati podršku za učitavanje podataka iz lokalne JSON datoteke, a ne iz mrežnog izvora.

Pa ako kreirate protokol koji sadrži nazive metoda, možete stvoriti implementaciju za internetski API i onu za podatke izvan mreže.

Ovo bi moglo izgledati ovako.

Protokol kaže samo: "Ako me udovoljavate, morate imati ove metode potpisa, ali mene nije briga za stvarnu implementaciju!"

Dakle, to je sjajno, možete stvoriti WebArticleRepository i LocalArticleRepository. Oboje će imati sve metode navedene u protokolu, ali možete napisati dvije potpuno različite implementacije.

Uključivanje: Ispitivanje jedinice

Upotreba protokola je također vrlo zgodna kad želite testirati svoj kôd, jer jednostavno možete stvoriti drugi objekt koji implementira protokol spremišta, ali umjesto toga vraća podsmiješne podatke.

Ako to koristite zajedno s ubrizgavanjem ovisnosti, stvarno je lako testirati određeni objekt.

Primjer

Recimo da imate model prikaza, a model pregleda dobiva svoje podatke putem spremišta.

Ako želite testirati model prikaza, zaglavili ste se u člancima koji će vam biti dohvaćeni s interneta.
To zapravo nije ono što želimo. Želimo da naš test bude što više determiniran. U ovom slučaju se članci preuzeti s interneta mogu s vremenom mijenjati, ne može postojati internetska veza u vrijeme pokretanja testova, poslužitelj može biti u prekidu, ... sve su to mogući scenariji u kojima naši testovi neće uspjeti, jer su izvan naše kontrole. A kad testiramo, želimo / trebamo imati kontrolu.

Srećom to je zapravo jednostavno riješiti.

Pozdrav, injekcije ovisnosti.

Trebate samo postaviti svojstvo ArticleRepo putem inicijalizatora. Zadani slučaj bit će onaj koji želite za svoj proizvodni kod i kad napišete jedinicu testa, možete spremiti spremište svojom inačicom.

Ali možda razmišljate, pa što je s vrstama? WebArticleRepository nije MockArticleRepository, pa se prevoditelj neće žaliti? Pa, ne ako protokol koristite kao tip. Na ovaj način obavještavamo prevodilac, dopuštamo sve onoliko koliko je u skladu s protokolom ArticleRepository (što rade i Web i MockArticleRepository).

Konačni bi kod izgledao ovako.

A u svom jedinstvenom testu to biste mogli zamijeniti ovako.

Sada imate potpunu kontrolu nad podacima koje vraća vaše spremište.

Super power-up: generički

To biste mogli još više, koristeći generičke podatke. Ako razmislite, većina spremišta uvijek ima iste operacije

  1. nabavite sve stvari
  2. nabavite neke stvari
  3. umetnite neke stvari
  4. izbrisati stvar
  5. ažurirati stvar

Pa, jedino što je drugačije je riječ 'stvar', pa bi ovo mogao biti odličan kandidat za korištenje protokola s generičkim podacima. Možda zvuči komplicirano, ali zapravo je to vrlo jednostavno učiniti.

Prvo ćemo protokol preimenovati u Repozitorij da bismo ga učinili više ... općenitim .
Tada ćemo ukloniti sve vrste članaka i zamijeniti ih magijom T. No, slovo T samo je zamjena za ... sve što želimo da bude. Trebamo samo označiti T kao povezanu vrstu protokola.

Dakle, ovaj protokol sada možemo koristiti za svaki model modela koji imamo.

1. Spremište članaka

Kompajler će zaključiti vrstu T u Article, jer smo primjenom metoda specificirali što je T. U ovom slučaju predmet članka.

2. Korisničko spremište

To je to.

Nadam se da vam se svidio članak i ako imate bilo kakva pitanja ili primjedbe, samo ih postavite u nastavku ili mi se obratite na Twitteru i neka razgovaramo.