Menu
CoddyTech

Pola Strategy

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Kotlin di Coddy. Pelajaran 45 dari 57.

Pola strategy menempatkan setiap variasi algoritma dalam class tersendiri di balik antarmuka bersama. Kode yang menggunakannya menyimpan satu strategi dan dapat menggantinya saat program berjalan:

interface Shipping {
    fun cost(kg: Int): Int
}
class Standard : Shipping {
    override fun cost(kg: Int) = 5 + kg
}
class Express : Shipping {
    override fun cost(kg: Int) = 15 + kg * 2
}

class Checkout(var shipping: Shipping) {
    fun total(price: Int, kg: Int) = price + shipping.cost(kg)
}

Di dalam main:

val checkout = Checkout(Standard())
println(checkout.total(100, 3))
checkout.shipping = Express()
println(checkout.total(100, 3))

Output:

108
121

Jika sebuah strategi hanya memiliki satu method, tipe fungsi sudah cukup. class tersebut menyimpan fungsi dan memanggilnya:

class Formatter(var style: (String) -> String) {
    fun show(words: List<String>) = words.joinToString(" ") { style(it) }
}

Di dalam main:

val f = Formatter { it.uppercase() }
println(f.show(listOf("hello", "world")))
f.style = { it.reversed() }
println(f.show(listOf("hello", "world")))

Output:

HELLO WORLD
olleh dlrow

Sebuah strategi menggantikan when di dalam algoritma. Dengan when, setiap opsi baru berarti mengedit algoritma. Dengan strategi, opsi baru berarti class atau lambda baru, dan Checkout tidak pernah berubah:

// tanpa strategi: setiap opsi baru mengharuskanmu mengubah fungsi ini
fun cost(kind: String, kg: Int) = when (kind) {
    "standard" -> 5 + kg
    else -> 15 + kg * 2
}
// dengan strategi: tambahkan class, biarkan Checkout tetap seperti semula
class Overnight : Shipping {
    override fun cost(kg: Int) = 40
}

Strategi sering dipilih berdasarkan data, seperti paket pelanggan, menggunakan peta atau pabrik kecil:

val discounts: Map<String, (Int) -> Int> = mapOf(
    "gold" to { price -> price * 80 / 100 },
    "silver" to { price -> price * 90 / 100 }
)

fun finalPrice(plan: String, price: Int) = discounts[plan]?.invoke(price) ?: price

Di dalam main:

println(finalPrice("gold", 200))
println(finalPrice("silver", 200))
println(finalPrice("basic", 200))

Output:

160
180
200
challenge icon

Tantangan

Mudah

Serangan hero adalah sebuah strategi. Interface Attack (dengan name dan damage(strength)) sudah disediakan. Tulis Sword (damage sebesar strength dikali 2), Bow (strength ditambah 5), dan Magic(mana) (strength dikali 3 saat mana minimal 10, jika tidak, 1). Hero(name, strength, attack) dapat mengubah attack-nya kapan saja, dan strike() mengembalikan Ada hits with sword for 20 tanpa memeriksa jenis attack yang dimilikinya.

Kode yang disediakan membaca name,strength, lalu perintah equip bow, equip magic 15, equip sword, atau strike, kemudian mencetak hasil setiap serangan.

Tulis kodemu di Sword.kt, Bow.kt, Magic.kt, Hero.kt, dan Attack.kt. Main.kt berisi kode input/output yang disediakan dan tidak boleh diedit.

Coba sendiri

fun main() {
    // Kode input/output yang disediakan: biarkan tetap seperti ini
    val input = generateSequence(::readLine).toList()
    val (name, strength) = input[0].split(",")
    val hero = Hero(name, strength.toInt(), Sword())
    for (cmd in input.drop(1)) {
        val p = cmd.split(" ")
        if (p[0] == "strike") {
            println(hero.strike())
            continue
        }
        hero.attack = when (p[1]) {
            "bow" -> Bow()
            "magic" -> Magic(p[2].toInt())
            else -> Sword()
        }
    }
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Playground Kotlin