0Pricing
Kotlin Academy · Lekcja

Praktyczne wzorce

Dekoratory z delegowaniem

Praktyczne wzorce to bezpłatna lekcja Kotlin Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Kotlin Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Kotlin Academy zawiera 4 lekcji w sumie.

Wzorzec dekoratora

Dekorator opakowuje obiekt, aby dodać zachowanie, zachowując ten sam interfejs. Słowo kluczowe by w Kotlinie sprawia, że tworzenie dekoratorów jest bardzo proste: należy przekazywać dalej wszystko i zastępować tylko te elementy, które są rozszerzane.

Komponent bazowy

Zaczynamy od prostego źródła danych. To źródło zostanie opakowane przez dekoratory.

interface DataSource {
    fun fetch(): String
}

class NetworkSource : DataSource {
    override fun fetch() = "raw-data"
}

fun main() {
    println(NetworkSource().fetch())
}

Dekorator logowania

Dekorator deleguje do opakowanego źródła i dodaje logowanie wokół wywołania, które go interesuje.

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())
}

Dekorator buforowania

Inny dekorator buforuje pierwszy wynik, dzięki czemu kolejne wywołania pomijają źródłową implementację.

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
}

Łączenie dekoratorów

Ponieważ każdy dekorator sam jest obiektem DataSource, można je łączyć. Kolejność ma znaczenie: zewnętrzny opakowuje wewnętrzny.

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())
}

Dekorator walidujący

Dekoratory mogą również sprawdzać dane wejściowe. Tutaj dekorator przeprowadza walidację przed delegowaniem do właściwego wykonawcy.

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"))
}

Opakowanie kolekcji tylko do odczytu

Delegowanie ułatwia tworzenie opakowań adaptujących. Tutaj opakowujemy listę i dodajemy własną metodę podsumowania, przekazując dalej wszystkie operacje listy.

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())
}

Zliczanie wywołań

Dekorator może w przejrzysty sposób śledzić metryki, co przydaje się do monitorowania bez ingerowania w rzeczywistą implementację.

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)
}

Dlaczego tutaj wygrywa delegowanie

Budowanie dekoratorów za pomocą dziedziczenia wymuszałoby oznaczenie klasy bazowej jako open i wiązałoby każdy dekorator z konkretną klasą. Delegowanie zależy tylko od interfejsu, dlatego dekoratory pozostają luźno powiązane i można je łatwo komponować.

Lista kontrolna wzorca

Aby zbudować dekorator oparty na delegowaniu:

  • Przyjmij opakowany obiekt jako private val
  • Deleguj interfejs za pomocą by
  • Zastępuj tylko rozszerzane składowe
  • Wewnątrz zastąpionej składowej wywołuj obiekt wewnętrzny

Łączymy wszystko

Dekoratory, adaptery i proxy wynikają naturalnie z delegowania klas. W połączeniu z małymi interfejsami pozwalają budować elastyczne, warstwowe systemy, które łatwo testować i rozszerzać.

Szybkie sprawdzenie

Sprawdź swoją wiedzę na temat praktycznych wzorców delegowania.

Podsumowanie

Zbudowano praktyczne dekoratory z użyciem delegowania:

  • Opakowania do logowania, buforowania, walidacji i zliczania
  • Łączenie dekoratorów, ponieważ każdy implementuje ten sam interfejs
  • Zastępowanie tylko rozszerzanych składowych i przekazywanie dalej pozostałych

To kończy kurs delegowania klas.

Często zadawane pytania

Czy lekcja „Praktyczne wzorce” jest bezpłatna?

Tak — pełny tekst „Praktyczne wzorce” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Kotlin Academy, przejdź na CoddyKit PRO. Kurs Kotlin Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Praktyczne wzorce”?

Dekoratory z delegowaniem Ćwiczysz Kotlin Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Kotlin Academy?

Nie wymagamy żadnego doświadczenia. Kotlin Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Praktyczne wzorce”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Kotlin Academy?

Tak. Każda lekcja Kotlin Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Słowo kluczowe by
  2. Delegowanie do składowych
  3. Delegowanie a dziedziczenie
  4. Praktyczne wzorce
← Powrót do Kotlin Academy