kulunvalvonnan käsite mahdollistaa sen, että rajoitamme sitä, miten tyyppejä, toimintoja ja muita ilmoituksia voidaan käyttää muulla koodilla. Swift tarjoaa viisi eritasoista Kulunvalvontaa, ja niiden täysimittainen hyödyntäminen voi olla ratkaisevan tärkeää, jotta voidaan kirjoittaa ohjelmia, joissa on selvästi erotetut huolenaiheet ja vankka rakenne.

kun Swiftissä määritellään jokin uusi tyyppi, ominaisuus tai funktio, sillä on oletusarvoisesti internal pääsytaso. Tämä tarkoittaa, että se on näkyvissä kaikille muille koodi, joka asuu samassa moduulissa — kuten sovellus, järjestelmän laajennus, puitteet, tai Swift-paketti.

esimerkiksi sanotaan, että rakennamme ostosovellusta ja että olemme määritelleet luokan nimeltä PriceCalculator, jonka avulla voimme laskea kokonaishinnan erilaisille tuotteille:

koska emme tällä hetkellä määrittele mitään eksplisiittistä pääsytasoa, PriceCalculator luokkamme (ja sen calculatePrice menetelmä) on käytettävissä mistä tahansa sovelluksessamme. Jos kuitenkin haluamme jakaa uuden luokkamme muiden moduulien kanssa (saatamme esimerkiksi toteuttaa sen pääsovelluksemme ja laajennuksen tai seuralaisen Apple Watch-sovelluksen välillä jakamassamme kehyksessä), meidän on tehtävä se public, jotta se näkyisi näissä ulkoisissa yhteyksissä:

edellä mainittu muutos ei kuitenkaan aivan riitä. Vaikka olemme nyt löytää luokan ulkopuolella moduuli, että se on määritelty, emme voi luoda mitään esiintymiä siitä-koska sen (implisiittinen) initializer on, kuten mikä tahansa muu koodi, internal oletuksena. Sen korjaamiseksi määritellään public initializer ,jonka jätämme tyhjäksi, koska sen sisällä ei ole varsinaista työtä tehtävänä:

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

pystymme nyt löytämään, alustamaan ja kutsumaan PriceCalculator: mme sekä sen moduulin sisä — että ulkopuolelta-fantastiseksi. Mutta sanotaan nyt, että haluamme myös aliluokittaa sen muokataksemme sitä tai lisätäksemme siihen uusia toimintoja. Vaikka se on tällä hetkellä mahdollista omassa moduulissa, se on jälleen jotain, joka on estetty sen ulkopuolella.

tämän muuttamiseksi meidän on käytettävä Swiftin tällä hetkellä avoiminta kulunvalvonnan tasoa, joka on asianmukaisesti nimetty open:

open class PriceCalculator { ...}

edellä mainitun muutoksen myötä voimme nyt luoda mukautettuja alaluokkia PriceCalculator minne tahansa-joilla voi olla uusia alustuksia, uusia ominaisuuksia ja uusia menetelmiä. Näin voisimme käyttää sitä toteuttamaan DiscountedPriceCalculator, jonka avulla voimme soveltaa annettua discount kaikkiin hintalaskelmiin:

edellä olemme määrittelemässä aivan uutta hintojen laskentamenetelmää, mutta olisi todennäköisesti paljon tarkoituksenmukaisempaa ohittaa ja muuttaa nykyistä calculatePrice – menetelmää, jonka perimme perusluokaltamme. Siten ei olisi epäselvyyttä siitä, mihin menetelmään soittaa, ja voisimme pitää kaksi luokkaamme yhdenmukaisina.

voidaksemme tehdä sen, meidän on jälleen merkittävä alkuperäinen julistus-tällä kertaa calculatePrice metodijulistuksemme-seuraavasti open:

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

kun edellä mainittu on käytössä, voimme nyt vapaasti ohittaa calculatePrice sen sijaan, että tarvitsisimme erillisen menetelmän:

siis internal, public ja open – joita käytetään julistuksen asteittaiseen avaamiseen yleiseen käyttöön ja muutettavaksi. Mutta voimme tietysti myös mennä toiseen suuntaan, ja piilottaa osia koodistamme paljastumiselta ja käytöltä. Aluksi voi tuntua kyseenalaiselta, mitä arvoa tällä on, mutta se voi todella auttaa meitä tekemään API: stamme paljon kapeamman ja tarkemman — mikä puolestaan voi helpottaa sen ymmärtämistä, testaamista ja käyttöä.

mennään siis nyt access – tason spektrin toiselle puolelle asti ja kurkistetaan kaikkein rajoittavimpaan tasoon – private. Mikä tahansa tyyppi, ominaisuus tai menetelmä, joka on merkitty koodilla private, näkyy vain omassa tyypissään (joka sisältää myös kyseisen tyypin laajennukset, jotka on määritelty samassa tiedostossa).

Kaikki, mitä tulisi pitää tietyntyyppisenä yksityisenä toteutusyksityiskohtana, tulisi todennäköisesti merkitä merkinnällä private. Esimerkiksi meidän hintalaskurimme discount tontti aiemmalta ajalta oli oikeasti tarkoitettu vain omaan luokkaansa käytettäväksi — joten mennään eteenpäin ja tehdään siitä kiinteistöstä yksityinen:

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

aiempi toteutuksemme toimii edelleen täsmälleen samalla tavalla kuin ennenkin, sillä discount jää kokonaan näkyviin DiscountedPriceCalculator – luokassamme. Jos kuitenkin haluaisimme hieman laajentaa tätä näkyvyyttä myös muihin saman tiedoston sisällä määriteltyihin tyyppeihin, meidän olisi käytettävä fileprivate — joka tekee juuri sitä, miltä se kuulostaa, se pitää ilmoituksen yksityisenä tiedostossa, jossa se on määritelty:

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

edellä mainitun muutoksen myötä voimme nyt käyttää discount – omaisuuttamme samassa tiedostossa määritellystä koodista — kuten tästä laajennuksesta UIAlertController, jonka avulla voimme helposti näyttää hintakuvauksen joukolle tuotteita hälytyksessä:

kun on kyse vapaista toiminnoista, tyypeistä ja laajennuksista, private ja fileprivate toimivat täsmälleen samoin. Ne ovat erilaisia vain, kun niitä sovelletaan ilmoituksiin, jotka on määritelty tietyn tyypin sisällä.

joten yhteenvetona, nämä ovat viisi tasoa kulunvalvonta, että Swift tällä hetkellä tarjoaa:

  • private pitää ominaisuuden tai toiminnon yksityisenä sulkutyypissään, mukaan lukien kaikki kyseisen tyypin laajennukset, jotka on määritelty samassa tiedostossa. Kun sitä sovelletaan ylätasoiseen tyyppiin, funktioon tai laajennukseen, se toimii samalla tavalla kuin fileprivate.
  • fileprivate tekee ilmoituksen näkyväksi koko tiedostossa, jossa se on määritelty, piilottaen sen kaikilta muilta koodeilta.
  • internal on oletuskäyttötaso ja tekee ilmoituksen näkyväksi koko moduulissa, jossa se on määritelty.
  • public paljastaa moduulinsa ulkopuolisen funktion, tyypin, laajennuksen tai ominaisuuden.
  • open mahdollistaa luokan aliluokan ja funktion tai ominaisuuden ohittamisen moduulinsa ulkopuolella.

yleisesti ottaen on usein parasta aloittaa mahdollisimman rajoittavalla pääsytasolla, joka tietyllä ilmoituksella käytännössä voi olla, ja avata asioita myöhemmin tarvittaessa. Näin rajoitamme mahdollisuuksia vuorovaikutukseen erilaisten tyyppiemme ja toimintojemme välillä, mikä voi aluksi tuntua huonolta asialta, mutta on usein todella välttämätöntä ylläpidettävien ja hyvin jäsenneltyjen järjestelmien rakentamiseksi.

Kiitos lukemisesta! 🚀

(huomaa, että tämä artikkeli ei mennyt mutaatiospesifisiin access-modifioijiin, kuten private(set). Niitä käsitellään tulevaisuudessa toisessa Perusartikkelissa.)

Support Swift by Sundell by checking out this sponsor:

Instabug: Ratkaise vikoja, kaatumisia ja muita ongelmia paljon nopeammin käyttämällä yksityiskohtaisia pinon jälkiä, verkkolokeja ja KÄYTTÖLIITTYMÄTAPAHTUMIA, jotka Instabug liittää automaattisesti kuhunkin vikailmoitukseen. Käyttää sekä minua että tuhansia iOS – kehitystiimejä ympäri maailmaa. Kokeile sitä ilmaiseksi ja integroida se vain yhdellä rivillä koodia.

Vastaa

Sähköpostiosoitettasi ei julkaista.