Uzorak delegacije u Kotlinu
1. Pregled
Mnogo je slučajeva upotrebe u kojima se delegiranje daje prednost nasljeđivanju. Kotlin za to ima veliku podršku na jezičnom nivou.
U ovom vodiču, razgovarat ćemo o Kotlinovoj izvornoj podršci za obrazac delegiranja i vidjeti to na djelu.
2. Provedba
Prvo, pretpostavimo da imamo primjer koda sa donjom strukturom u biblioteci treće strane:
sučelje Producer {fun produce (): String} class ProducerImpl: Producer {override fun produce () = "ProducerImpl"}
Sljedeći, ukrasimo postojeću provedbupomoću ključne riječi "by" i dodajte dodatnu potrebnu obradu:
klasa EnhancedProducer (privatni valni delegat: Producer): Producent prema delegatu {override fun produce () = "$ {delegate.produce ()} i EnhancedProducer"}
Dakle, u ovom smo primjeru naznačili da EnhancedProducer razred će enkapsulirati a delegat objekt tipa Proizvođač. Također, može koristiti funkcionalnost sustava Windows Proizvođač provedba.
Na kraju, provjerimo da li radi prema očekivanjima:
val proizvođač = EnhancedProducer (ProducerImpl ()) assertThat (produce.produce ()). isEqualTo ("ProducerImpl i EnhancedProducer")
3. Koristite slučajeve
Pogledajmo sada dva uobičajena slučaja korištenja uzorka delegiranja.
Prvo, možemo koristiti obrazac delegiranja implementirati više sučelja koristeći postojeće implementacije:
klasa CompositeService: UserService by UserServiceImpl (), MessageService by MessageServiceImpl ()
Drugo, možemo koristiti delegiranje kako bi se poboljšala postojeća provedba.
Ovo potonje je ono što smo učinili u prethodnom odjeljku. Ali, stvarniji primjer poput ovog u nastavku posebno je koristan kada ne možemo izmijeniti postojeću implementaciju - na primjer, kod biblioteke treće strane:
class SynchronizedProducer (private val delegat: Producer): Producer by delegat {private val lock = ReentrantLock () override fun produce (): String {lock.withLock {return delegate.produce ()}}}
4. Delegiranje nije nasljeđivanje
Sad se toga uvijek moramo sjećati delegat ne zna ništa o dekorateru. Dakle, ne bismo trebali pokušavati GoF metoda predloška-priličan pristup s njima.
Razmotrimo primjer:
sučelje Usluga {val sjeme: Int zabavno posluživanje (akcija: (Int) -> Jedinica)} klasa ServiceImpl: Usluga {prevladati val sjeme = 1 nadjačati zabavno posluživanje (radnja: (Int) -> Jedinica) {akcija (sjeme)}} class ServiceDecorator: Service by ServiceImpl () {override val seed = 2}
Ovdje je delegat (UslugaImpl) koristi svojstvo definirano u zajedničkom sučelju, a mi ga zamjenjujemo u dekorateru (ServiceDecorator). Međutim, to ne utječe na obradu delegata:
val usluga = ServiceDecorator () service.serve {assertThat (it) .isEqualTo (1)}
Konačno, važno je napomenuti da se u Kotlinu možemo delegirati ne samo sučelja već i odvojena svojstva.
5. Zaključak
U ovom vodiču govorili smo o delegiranju Kotlinovog sučelja - kada ga treba koristiti, kako ga konfigurirati i o upozorenjima.
Kao i obično, cjeloviti izvorni kod za ovaj članak dostupan je na GitHubu.