Vzor delegovania v Kotline
1. Prehľad
Existuje veľa prípadov použitia, v ktorých sa delegovanie uprednostňuje pred dedičstvom. Kotlin má k tomu veľkú podporu na jazykovej úrovni.
V tomto návode povieme si o Kotlinovej natívnej podpore vzoru delegovania a uvidíte to v akcii.
2. Implementácia
Najprv predpokladajme, že máme príklad kódu so štruktúrou nižšie v knižnici tretej strany:
interface Producer {fun produce (): String} class ProducerImpl: Producer {override fun produce () = "ProducerImpl"}
Ďalšie, poďme ozdobiť existujúcu implementáciupomocou kľúčového slova „podľa“ a pridať ďalšie potrebné spracovanie:
class EnhancedProducer (private val delegate: Producer): Producer by delegate {override fun produce () = "$ {delegate.produce ()} and EnhancedProducer"}
V tomto príklade sme teda naznačili, že Vylepšený výrobca trieda zapuzdrí a delegovať objekt typu Výrobca. A môže tiež využívať funkcie z Výrobca implementácia.
Nakoniec overíme, či funguje podľa očakávania:
val producer = EnhancedProducer (ProducerImpl ()) assertThat (producer.produce ()). isEqualTo ("ProducerImpl a EnhancedProducer")
3. Používajte puzdrá
Teraz sa pozrime na dva bežné prípady použitia vzoru delegovania.
Najprv môžeme použiť vzor delegovania implementovať viac rozhraní pomocou existujúcich implementácií:
trieda CompositeService: UserService od UserServiceImpl (), MessageService od MessageServiceImpl ()
Po druhé, môžeme použiť delegovanie zlepšiť existujúcu implementáciu.
To posledné je to, čo sme urobili v predchádzajúcej časti. Reálnejší príklad, ako je tento, je však zvlášť užitočný, keď nemôžeme upraviť existujúcu implementáciu - napríklad kód knižnice tretej strany:
class SynchronizedProducer (private val delegate: Producer): Producer by delegate {private val lock = ReentrantLock () override fun produce (): String {lock.withLock {return delegate.produce ()}}}
4. Delegácia nie je dedičstvo
Teraz si to musíme stále pamätať delegát nevie nič o dekoratérovi. Nemali by sme teda vyskúšať Metóda šablóny GoF-aký prístup s nimi.
Uvažujme príklad:
Service interface {val seed: Int fun serve (action: (Int) -> Unit)} class ServiceImpl: Service {override val seed = 1 override fun serve (action: (Int) -> Unit) {action (seed)}} class ServiceDecorator: Service by ServiceImpl () {override val seed = 2}
Tu delegát (ServiceImpl) používa vlastnosť definovanú v spoločnom rozhraní a v dekoratéri ju prepíšeme (ServiceDecorator). Nemá to však vplyv na spracovanie delegáta:
val service = ServiceDecorator () service.serve {assertThat (it) .isEqualTo (1)}
Na záver je dôležité poznamenať, že v Kotline môžeme delegovať nielen na rozhrania, ale aj na samostatné vlastnosti.
5. Záver
V tomto výučbe sme hovorili o delegovaní rozhrania Kotlin - kedy by sa malo používať, ako ho nakonfigurovať a o jeho výhradách.
Úplný zdrojový kód tohto článku je ako obvykle k dispozícii na serveri GitHub.