Pattern pratici
Crei decorator con la delega
Pattern pratici è una lezione Kotlin Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Kotlin Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Kotlin Academy include 4 lezioni in totale.
Il pattern Decorator
Un decoratore avvolge un oggetto per aggiungere comportamento mantenendo la stessa interfaccia. La parola chiave by di Kotlin rende i decoratori semplicissimi: inoltri tutto e sottoponga a override solo le parti che vuole potenziare.
Un componente di base
Si parte da una semplice sorgente di dati. I decoratori la avvolgeranno.
interface DataSource {
fun fetch(): String
}
class NetworkSource : DataSource {
override fun fetch() = "raw-data"
}
fun main() {
println(NetworkSource().fetch())
}Un decoratore per il logging
Il decoratore delega alla sorgente avvolta e aggiunge il logging attorno alla chiamata che gli interessa.
interface DataSource { fun fetch(): String }
class NetworkSource : DataSource { override fun fetch() = "raw-data" }
class LoggingSource(private val inner: DataSource) : DataSource by inner {
override fun fetch(): String {
println("fetching...")
val result = inner.fetch()
println("done")
return result
}
}
fun main() {
println(LoggingSource(NetworkSource()).fetch())
}Un decoratore per la cache
Un altro decoratore memorizza nella cache il primo risultato, così le chiamate successive evitano la sorgente sottostante.
interface DataSource { fun fetch(): String }
class NetworkSource : DataSource { override fun fetch() = "raw-data" }
class CachingSource(private val inner: DataSource) : DataSource by inner {
private var cached: String? = null
override fun fetch(): String {
return cached ?: inner.fetch().also { cached = it }
}
}
fun main() {
val s = CachingSource(NetworkSource())
println(s.fetch())
println(s.fetch()) // served from cache
}Comporre i decoratori
Poiché ogni decoratore è a sua volta un DataSource, è possibile concatenarli. L'ordine è importante: l'esterno avvolge quello interno.
interface DataSource { fun fetch(): String }
class NetworkSource : DataSource { override fun fetch() = "raw-data" }
class LoggingSource(private val inner: DataSource) : DataSource by inner {
override fun fetch(): String { println("log"); return inner.fetch() }
}
class CachingSource(private val inner: DataSource) : DataSource by inner {
private var c: String? = null
override fun fetch() = c ?: inner.fetch().also { c = it }
}
fun main() {
val s = LoggingSource(CachingSource(NetworkSource()))
println(s.fetch())
println(s.fetch())
}Un decoratore di validazione
I decoratori possono anche controllare gli input. Qui un decoratore esegue la validazione prima di delegare al componente di lavoro reale.
interface Processor { fun process(input: String): String }
class UpperProcessor : Processor { override fun process(input: String) = input.uppercase() }
class ValidatingProcessor(private val inner: Processor) : Processor by inner {
override fun process(input: String): String {
require(input.isNotBlank()) { "empty input" }
return inner.process(input)
}
}
fun main() {
println(ValidatingProcessor(UpperProcessor()).process("hello"))
}Wrapper di raccolta in sola lettura
La delegazione semplifica la creazione di wrapper adattatori. Qui avvolgiamo una lista e aggiungiamo un metodo summary personalizzato, inoltrando tutte le operazioni della lista.
class SummarizedList(private val inner: List<Int>) : List<Int> by inner {
fun total() = inner.sum()
}
fun main() {
val list = SummarizedList(listOf(1, 2, 3))
println(list.size)
println(list.total())
}Conteggio delle chiamate
Un decoratore può monitorare le metriche in modo trasparente, utile per il monitoraggio senza modificare l'implementazione reale.
interface Service { fun call(): String }
class RealService : Service { override fun call() = "ok" }
class CountingService(private val inner: Service) : Service by inner {
var calls = 0
private set
override fun call(): String {
calls++
return inner.call()
}
}
fun main() {
val s = CountingService(RealService())
s.call(); s.call()
println(s.calls)
}Perché qui conviene la delegazione
Creare decoratori tramite ereditarietà obbligherebbe la classe base a essere open e legherebbe ogni decoratore a una classe concreta. La delegazione dipende solo dall'interfaccia, quindi i decoratori restano debolmente accoppiati e componibili.
Checklist del pattern
Per creare un decoratore basato sulla delegazione:
- Accetti l'oggetto avvolto come
private val - Deleghi l'interfaccia con
by - Sottoponga a override solo i membri che vuole potenziare
- Chiami l'oggetto interno all'interno dell'override
Riunire i concetti
Decoratori, adattatori e proxy derivano tutti naturalmente dalla delegazione delle classi. In combinazione con interfacce piccole, consentono di creare sistemi flessibili e stratificati, facili da testare ed estendere.
Verifica rapida
Verifichi la Sua comprensione dei pattern pratici di delegazione.
Riepilogo
Ha creato decoratori pratici con la delegazione:
- Wrapper per logging, cache, validazione e conteggio
- Composizione di decoratori, poiché ognuno implementa la stessa interfaccia
- Override solo dei membri potenziati; inoltro di tutti gli altri
Questo completa il corso sulla delegazione delle classi.
Domande Frequenti
La lezione «Pattern pratici» è gratuita?
Sì — il testo completo di «Pattern pratici» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Kotlin Academy, passa a CoddyKit PRO. Il corso Kotlin Academy include 4 lezioni in totale.
Cosa imparerò in «Pattern pratici»?
Crei decorator con la delega Eserciti Kotlin Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Kotlin Academy?
Non è richiesta alcuna esperienza precedente. Kotlin Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.
Quanto tempo richiede la lezione «Pattern pratici»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Kotlin Academy?
Sì. Ogni lezione Kotlin Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- La keyword by
- Delega ai membri
- Delega e ereditarietà
- Pattern pratici