S.O.L.I.D Principle - Liskov Substitution Principle (LSP)

amalhanaja

Alfian Akmal Hanantio

Posted on June 20, 2021

S.O.L.I.D Principle - Liskov Substitution Principle (LSP)

Open Closed Principle yang sudah saya tulis di artikel sebelumnya merupakan salah satu kunci dari konsep Pemrograman Berbasis Objek (Object Oriented Programming) dimana memungkinkan kamu untuk menulis code yang robust, dapat dimaintenance, dan reusable software components. Namun hanya mengadopsi prinsip ini saja tidak cukup untuk memastikan bahwa kamu dapat mengubah salah satu bagian dari sistemmu tanpa merusak bagian-bagian yang lain. class dan interface yang kamu miliki juga perlu mengadopsi Liskov Substitution Principle (LSP) untuk menghindari side-effect.

Liskov Substitution Principle ini memperluas Open Closed Principle dengan memfokuskan pada behavior dari superclass dan turunannya.

Apa itu Liskov Substitution Principle (LSP)

💡 If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T. ~ Barbara Liskov

Kemudian Robert C. Martin merumuskan kembali definisi dari Liskov Substitution Principle yang dikemukakan oleh Barbara Liskov

💡 Subtypes must be substitutable for their base types.

Prinsip ini dapat juga diartikan bahwa objek-objek dari superclass seharusnya dapat digantikan dengan objek-objek yang merupakan turunan dari superclass tanpa merusak aplikasi. Dimana mengharuskan objek-objek dari turunan superclass memiliki behavior yang sama dengan superclassnya.

Kenapa LSP ini Penting ?

Pelanggaran LSP akan membuat code anda bau. Kita mungkin telah mengeneralisasi sebuah konsep secara premature dan membuat superclass dimana tidak diperlukan. Kebutuhan dimasa mendatang untuk konsep tersebut mungkin tidak sesuai dengan hierarki class yang kita buat.

Jika code klien tidak dapat menggantikan referensi superclass dengan objek-obej subclass secara bebas, maka akan dipaksa untuk melakukan pemeriksaan instanceof dan menangani beberapa subclass secara kusus. Jika code seperti ini tersebar di seluruh code kita maka akan sulit untuk maintenancenya.

open class Product {
    protected val _discount: Double
    fun getDiscount(): Double {
        return _discount
    }
}
Enter fullscreen mode Exit fullscreen mode
class SpecialProduct : Product() {
    fun applyExtraDiscount() {
        _discount = _discount * 0.2
    }
}
Enter fullscreen mode Exit fullscreen mode
fun main(args: Array<String>) {
    val birds = listOf<Product>(Product(), SpecialProduct())
    birds.forEach { it ->
         if (it is SpecialProduct) it.applyExtraDiscount()
         println(it.getDiscount())
    }
}
Enter fullscreen mode Exit fullscreen mode

Setiap kali kita menambahkan atau memodifikasi subclass, kita harus menyusuri code base kita dan merubahnya di beberapa tempat, ini akan sulit dilakukan dan rawan akan kesalahan.

Solusi LSP

Code diatas berarti objek Produk tidak dapat digantikan oleh objek SpecialProduct karena kita melakukan validasi bahwa jika produk merupakan SpecialProduk maka kita akan memanggil fungsi applyExtraDiscount().

agar SpecialProduct dapat digunakan untuk menggantikan superclassnya maka kita akan menggunakan prinsip “Tell, don’t ask!”, dimana akan membantu kita untuk mengeliminasi type casting / type checking.

class SpecialProduct : Product() {

    override fun getDiscount() {
        applyExtraDiscount()
        return _discount
    }
    fun applyExtraDiscount() {
        _discount = _discount * 0.2
    }
}
Enter fullscreen mode Exit fullscreen mode
fun main(args: Array<String>) {
    val birds = listOf<Product>(Product(), SpecialProduct())
    birds.forEach { it ->
         println(it.getDiscount())
    }
}
Enter fullscreen mode Exit fullscreen mode

dengan begini kita tidak memerlukan typecasting karena kita telah mengubah method dengan cara mengoverride dan memanggil fungsi applyExtraDiscount() di dalamnya dengan begitu tidak diperlukan lagi untuk melakukan pengecekan bahwa untuk SpecialProduct. Serta code yang kita miliki jadi lebih robust, testable, dan maintenable karena telah mengikuti LSP.

Akhir Kata

Liskov Substitution Principle memperluas Open Closed Principle dan membuat kita dapat menggantikan objek dari superclass dengan objek-objeck turunannya tanpa merusak program yang sudah ada. Serta membantu kita untuk membuat hierarki yang sesuai antar tipe, dimana akan menjamin program kita untuk berjalan dengan benar tanpa side-effect yang tidak diinginkan.

💖 💪 🙅 🚩
amalhanaja
Alfian Akmal Hanantio

Posted on June 20, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related