Dekoratör Deseni
Coddy'nin Kotlin Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 47 / 57.
decorator deseni, bir nesneyi aynı arayüze sahip başka bir nesneyle sararak ona davranış ekler. Decorator, sardığı nesneye yönlendirme yapar ve kendi işlevini ekler; bu nedenle decorator'lar üst üste eklenebilir:
interface Coffee {
fun cost(): Int
fun description(): String
}
class Espresso : Coffee {
override fun cost() = 200
override fun description() = "espresso"
}
class Milk(private val inner: Coffee) : Coffee {
override fun cost() = inner.cost() + 50
override fun description() = inner.description() + ", milk"
}
class Syrup(private val inner: Coffee) : Coffee {
override fun cost() = inner.cost() + 30
override fun description() = inner.description() + ", syrup"
}main içinde:
val order = Syrup(Milk(Milk(Espresso())))
println("${order.description()}: ${order.cost()}")Çıktı:
espresso, milk, milk, syrup: 330Dekoratörler sonucu değiştirdiğinde sıraları önemlidir: her biri, içindeki nesnenin döndürdüğü değer üzerinde çalışır:
interface Text {
fun render(): String
}
class Word(private val w: String) : Text {
override fun render() = w
}
class Bracket(private val inner: Text) : Text {
override fun render() = "[" + inner.render() + "]"
}
class Twice(private val inner: Text) : Text {
override fun render() = inner.render() + inner.render()
}main içinde:
println(Twice(Bracket(Word("hi"))).render())
println(Bracket(Twice(Word("hi"))).render())Çıktı:
[hi][hi]
[hihi]by ile bir dekoratör yalnızca değiştirdiği üyeleri yazar ve geri kalanını otomatik olarak yönlendirir:
interface Source {
fun read(): String
fun name(): String
}
class FileSource(private val content: String) : Source {
override fun read() = content
override fun name() = "notes.txt"
}
class Censored(private val inner: Source, private val word: String) : Source by inner {
override fun read() = inner.read().replace(word, "***")
}main içinde:
val src = Censored(FileSource("the secret plan"), "secret")
println("${src.name()}: ${src.read()}")Çıktı:
notes.txt: the *** planDekoratörler program çalışırken, örneğin bir müşterinin seçimlerinden oluşturulurken, alt sınıf kod yazılırken tek bir birleşimi sabitler. Alt sınıflar olarak üç ek, her birleşim için bir sınıf gerektirirdi; dekoratörler olarak fold bunları bir listeden üst üste ekler:
interface Coffee {
fun cost(): Int
}
class Espresso : Coffee {
override fun cost() = 200
}
class Extra(private val inner: Coffee, private val price: Int) : Coffee {
override fun cost() = inner.cost() + price
}main içinde:
val prices = mapOf("milk" to 50, "syrup" to 30, "cream" to 70)
val choices = listOf("milk", "cream", "milk")
val coffee = choices.fold<String, Coffee>(Espresso()) { c, extra -> Extra(c, prices.getValue(extra)) }
println(coffee.cost())Çıktı:
370Görev
KolayPizza'lar, sağlanan Pizza arayüzünün (price() ve toppings() ile) dekoratörleri kullanılarak oluşturulur. Base'i (800, malzeme yok) ve Cheese (+150, cheese ekler), Olives (+100, olives ekler) ile her şeyi iki katına çıkaran ve malzemelerini iki kez tekrarlayan DoubleUp dekoratörlerini yazın. Ardından Base'ten başlayan ve her ad için sırayla bir dekoratörle saran build(names) işlevini yazın (cheese, olives veya double).
Sağlanan kod, virgülle ayrılmış adların bulunduğu satırları veya plain satırını okur, her pizzayı oluşturur ve 1050: cheese, olives veya 800: plain yazdırır.
Kodunuz Base.kt, Cheese.kt, Olives.kt, DoubleUp.kt, Build.kt ve Pizza.kt dosyalarına gider. Main.kt sağlanan giriş/çıkış kodunu içerir ve düzenlenemez.
Kendin dene
fun main() {
// Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
val input = generateSequence(::readLine).toList()
for (line in input) {
val names = if (line == "plain") listOf() else line.split(",")
val pizza = build(names)
val toppings = pizza.toppings()
println("${pizza.price()}: " + if (toppings.isEmpty()) "plain" else toppings.joinToString(", "))
}
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1Sınıflar ve Nesneler
Dosyalarla ÇalışmaSınıfları TanımlamaBirincil Yapıcılarinit Blokları ve Doğrulamaİkincil YapıcılarTekrar - Kütüphane Kartı4Kalıtım
Açık Sınıflar ve Alt SınıflarÜyeleri Geçersiz Kılmasuper ve YapıcılarSoyut SınıflarTekrar - Personel Dizini2Özellikler ve Kapsülleme
Özel ErişimcilerGörünürlük DeğiştiricileriÖzel Setter'larlazy ve lateinitTekrar - Banka Hesabı5Arayüzler
Arayüz BildirimleriVarsayılan MetotlarBirden Çok ArayüzTür Olarak ArayüzlerÖzet - Ödeme Yöntemleri8Generic'ler
Generic FonksiyonlarGeneric SınıflarTür Kısıtlamalarıin ve out ile VaryansTekrar - Öncelik Kuyruğu11Proje: Kütüphane Yönetimi
Kitaplar ve ÜyelerKitap Ödünç AlmaKendi başına pratik yap: Kotlin playground