Pola Singleton
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Kotlin di Coddy. Pelajaran 42 dari 57.
design pattern adalah solusi teruji untuk masalah desain yang berulang kali muncul. Pola singleton memastikan sebuah class memiliki tepat satu instance yang dapat diakses oleh seluruh program. Di Kotlin, deklarasi object adalah singleton: deklarasi ini dibuat sekali, saat pertama kali digunakan, dan tetap aman meskipun beberapa thread dimulai pada saat yang sama:
object Settings {
var theme = "light"
var fontSize = 14
}
fun openEditor() = "editor in ${Settings.theme} theme"Di dalam main:
Settings.theme = "dark"
println(openEditor())
println(Settings.fontSize)Output:
editor in dark theme
14Singleton menyimpan state yang digunakan bersama oleh berbagai bagian program. Jaga state tersebut tetap privat dan ubah hanya melalui method, sehingga setiap perubahan mengikuti aturan yang sama:
object Metrics {
private val hits = mutableMapOf<String, Int>()
fun hit(page: String) { hits[page] = (hits[page] ?: 0) + 1 }
fun report() = hits.entries.joinToString { "${it.key}=${it.value}" }
}
fun home() = Metrics.hit("home")
fun about() = Metrics.hit("about")Di dalam main:
home(); about(); home()
println(Metrics.report())Output:
home=2, about=1Saat instance tunggal memerlukan data penyiapan, class dengan private constructor dapat membuatnya di companion object pada permintaan pertama, lalu mengembalikan instance yang sama pada permintaan berikutnya:
class Database private constructor(val url: String) {
companion object {
private var instance: Database? = null
fun connect(url: String): Database =
instance ?: Database(url).also { instance = it }
}
}
Di dalam main:
val a = Database.connect("db://main")
val b = Database.connect("db://other")
println(a === b)
println(b.url)Output:
true
db://mainGunakan singleton secukupnya. Singleton adalah state global: kode apa pun dapat mengubahnya, sehingga tidak jelas siapa yang bergantung padanya, dan pengujian tidak dapat dimulai dari salinan yang baru. Singleton cocok untuk hal yang memang hanya ada satu per program, seperti konfigurasi atau logger. Jika hanya sebagian program yang membutuhkan object, berikan object itu sebagai parameter dengan tipe interface, sehingga pengujian dapat memberikan object palsu sebagai gantinya:
interface Clock { fun now(): Long }
object SystemClock : Clock { override fun now() = System.currentTimeMillis() }
class Session(private val clock: Clock) { // dependensinya terlihat
val started = clock.now()
}
val session = Session(SystemClock) // pengujian meneruskan Clock palsuTantangan
MudahLengkapi singleton Logger. Singleton ini memiliki minLevel yang bisa diubah (debug, info, warn, atau error, dalam urutan tersebut). log(level, message) menyimpan [WARN] disk low jika levelnya setidaknya minLevel. Jika tidak, fungsi ini menghitung pesan tersebut dalam dropped, yang bisa dibaca tetapi tidak bisa diubah dari luar kode. entries adalah list hanya-baca yang berisi baris tersimpan, dan count(level) mengembalikan jumlah baris tersimpan dengan level tersebut.
Fungsi helper dalam Functions.kt sudah disediakan: fungsi-fungsi tersebut mengakses Logger yang sama dari file lain. Kode yang disediakan membaca level minimum, lalu baris dengan format level,message, kemudian mencetak setiap entri dan errors: 1, dropped: 2.
Tulis kodemu di Logger.kt dan Functions.kt. Main.kt berisi kode input/output yang disediakan dan tidak boleh diedit.
Coba sendiri
fun main() {
// Kode input/output yang disediakan: biarkan apa adanya
val input = generateSequence(::readLine).toList()
Logger.minLevel = input[0]
for (line in input.drop(1)) {
val (level, message) = line.split(",", limit = 2)
when (level) {
"debug" -> debug(message)
"info" -> info(message)
"warn" -> warn(message)
else -> error(message)
}
}
for (e in Logger.entries) println(e)
println("errors: ${Logger.count("error")}, dropped: ${Logger.dropped}")
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Objek
1class dan object
Bekerja dengan fileMendefinisikan classKonstruktor utamaBlok init dan validasiKonstruktor sekunderRingkasan: Kartu Perpustakaan2property dan Enkapsulasi
Accessor KustomModifier VisibilitasSetter Privatlazy dan lateinitRingkasan: Rekening Bank5Interface
Mendeklarasikan Interfacemethod DefaultBeberapa InterfaceInterface sebagai TipeUlasan: Metode Pembayaran11Proyek: Pengelolaan Perpustakaan
Buku dan AnggotaPeminjaman BukuLatihan sendiri: Playground Kotlin