conceptul de control al accesului ne permite să restricționăm modul în care tipurile, funcțiile și alte declarații pot fi accesate prin alt cod. Swift oferă cinci niveluri diferite de control al accesului, iar utilizarea deplină a acestora poate fi crucială pentru a scrie programe care au preocupări clar separate și o structură robustă.

când definim orice tip, proprietate sau funcție nouă în Swift, acesta va avea implicit nivelul de acces internal. Aceasta înseamnă că va fi vizibil pentru toate celelalte coduri care se află în același modul — cum ar fi o aplicație, o extensie de sistem, un cadru sau un pachet Swift.

ca exemplu, să spunem că construim o aplicație de cumpărături și că am definit o clasă numită PriceCalculator care ne permite să calculăm prețul total pentru o serie de produse:

deoarece în prezent nu specificăm niciun nivel de acces explicit, clasa noastră PriceCalculator (și metoda sa calculatePrice) vor fi accesibile de oriunde din aplicația noastră. Cu toate acestea, dacă dorim să împărtășim noua noastră clasă cu alte module (am putea, de exemplu, să o implementăm într-un cadru pe care îl împărtășim între aplicația noastră principală și o extensie sau o aplicație Apple Watch însoțitoare), atunci va trebui să o facem public pentru a fi vizibilă în acele contexte externe:

cu toate acestea, schimbarea de mai sus nu este suficientă. În timp ce acum putem găsi clasa noastră în afara modulului în care este definită, nu putem crea instanțe ale acesteia — deoarece inițializatorul său (implicit) este, la fel ca orice alt cod, internal în mod implicit. Pentru a remedia acest lucru, să definim un inițializator public, pe care îl vom lăsa gol, deoarece nu există nicio lucrare reală de făcut în cadrul acestuia:

public class PriceCalculator { public init() {} ...}

acum suntem capabili să găsim, să inițializăm și să apelăm PriceCalculator atât în interiorul, cât și în afara modulului său — fantastic. Dar să spunem acum că căutăm, de asemenea, să o subclasăm pentru a o modifica sau pentru a adăuga noi funcționalități. Deși acest lucru este posibil în prezent în propriul modul, este din nou ceva care este împiedicat în afara acestuia.

pentru a schimba acest lucru, va trebui să folosim cel mai deschis nivel de control al accesului al Swift, care este denumit în mod corespunzătoropen:

open class PriceCalculator { ...}

cu schimbarea de mai sus în loc, putem crea acum subclase personalizate de PriceCalculator oriunde — care pot avea noi inițializatori, proprietăți noi și metode noi. Iată cum am putea folosi asta pentru a implementa un DiscountedPriceCalculator, care ne permite să aplicăm un discount dat tuturor calculelor de preț:

mai sus definim o nouă metodă de calcul a prețurilor, dar ar fi, fără îndoială, mult mai potrivit să suprascriem și să modificăm metoda existentă calculatePrice pe care am moștenit-o din clasa noastră de bază. În acest fel, nu ar exista nici o confuzie în jurul metodei de apelare și am putea păstra cele două clase consecvente.

pentru a putea face acest lucru, trebuie din nou să marcăm declarația originală — de data aceasta Declarația noastră de metodă open:

open class PriceCalculator { public init() {} open func calculatePrice(for products: ) -> Int { ... }}

cu cele de mai sus în loc, acum putem suprascrie liber calculatePrice, mai degrabă decât să creăm o metodă separată:

deci sunt internal, public și open — care sunt folosite pentru a deschide treptat o declarație pentru uz public și modificare. Dar putem, desigur, să mergem și în altă parte și să ascundem părți ale codului nostru de a fi descoperite și folosite. La început, poate părea discutabil care este valoarea în acest sens, dar ne poate ajuta cu adevărat să facem API — ul nostru mult mai îngust și mai concentrat-ceea ce, la rândul său, poate face mai ușor de înțeles, testat și utilizat.

deci, să mergem acum până la cealaltă parte a spectrului nivelului de acces și să aruncăm o privire la cel mai restrictiv nivel — private. Orice tip, proprietate sau metodă marcată ca private va fi vizibilă numai în propriul tip (care include și extensii pentru acel tip definite în același fișier).

orice lucru care ar trebui considerat un detaliu privat de implementare a unui anumit tip ar trebui, fără îndoială, să fie marcat ca private. De exemplu, calculatorul nostru de prețuri discount proprietatea de dinainte a fost într-adevăr menită să fie utilizată doar în propria clasă — așa că haideți să mergem mai departe și să facem acea proprietate privată:

class DiscountedPriceCalculator: PriceCalculator { private let discount: Int ...}

implementarea noastră anterioară va continua să funcționeze exact la fel ca înainte, deoarece discount va rămâne în întregime vizibilă în clasa noastră DiscountedPriceCalculator. Cu toate acestea, dacă am dori să extindem ușor această vizibilitate pentru a include și alte tipuri definite în același fișier, ar trebui să folosim fileprivate — care face exact ceea ce pare, păstrează o declarație privată în fișierul definit în:

class DiscountedPriceCalculator: PriceCalculator { fileprivate let discount: Int ...}

cu schimbarea de mai sus, putem accesa acum proprietatea noastră discount din codul asociat definit în același fișier — cum ar fi această extensie pe UIAlertController care ne permite să afișăm cu ușurință o descriere a prețului pentru o serie de produse într-o alertă:

când vine vorba de funcții libere, tipuri și extensii, private și fileprivate acționează exact la fel. Ele sunt diferite numai atunci când sunt aplicate declarațiilor care sunt definite într-un tip.

deci, pentru a rezuma, acestea sunt cele cinci niveluri de control al accesului pe care Swift le oferă în prezent:

  • private păstrează o proprietate sau o funcție privată în cadrul tipului său de închidere, inclusiv orice extensii pe acel tip care sunt definite în același fișier. Atunci când este aplicat la un tip de nivel superior, funcție sau extensie, acționează în același mod ca și fileprivate.
  • fileprivate face o declarație vizibilă în întregul fișier în care este definită, în timp ce o ascunde de toate celelalte coduri.
  • internal este nivelul de acces implicit și face o declarație vizibilă în întregul modul în care este definit.
  • public dezvăluie o funcție, tip, extensie sau proprietate în afara modulului său.
  • open permite ca o clasă să fie subclasată și o funcție sau o proprietate să fie înlocuită, în afara modulului său.

în general, este adesea cel mai bine să începeți cu cel mai restrictiv nivel de acces pe care o anumită declarație îl poate avea practic și apoi să deschideți lucrurile mai târziu, dacă este necesar. În acest fel, limităm căile de interacțiune între diferitele noastre tipuri și funcții, ceea ce poate părea la început un lucru rău, dar este adesea cu adevărat esențial pentru a construi sisteme întreținute și bine structurate.

Vă mulțumim pentru lectură!

(rețineți că acest articol nu a intrat în modificatori de acces specifici mutației, cum ar fi private(set). Acestea vor fi acoperite de un alt articol de bază în viitor.)

suport Swift de Sundell prin verificarea acest sponsor:

Instabug: Rezolva bug – uri, accidente și alte probleme mult mai rapid folosind urmele detaliate stivă, jurnalele de rețea și evenimente UI care Instabug se atașează automat la fiecare raport de eroare. Folosit atât de mine, cât și de mii de echipe de dezvoltare iOS din întreaga lume. Încercați-l gratuit și integrați-l cu o singură linie de cod.

Lasă un răspuns

Adresa ta de email nu va fi publicată.