SOLID Principle - Liskov Substitution Principle ?
Kita nostalgia dahulu ke masa lalu ..
Lagu Tak Akan Terganti dari Kahitna
Lagu lama yang menyatakan bahwa seseorang itu tidak pernah terganti karena rasa cinta dan sayang terhadapnya.
So cweeet.. dan so romantis.
Tapi di dunia Software Engineering apakah sama ?
Aaah, tentu saja tidaak..
Apalagi di lingkungan Object Oriented.
Dimana hampir semua nya dianggap Object yang bisa dipertukarkan..
Dengan seenaknya kita sebagai Software Engineer bisa mempertukarkan dan mempermainkan object-object yang ada di memori dan di class yang kita buat.
Demikian sadisnya dan brutalnya sehingga yang penting kita bisa melakukan :
- Inheritance
- Poliymorphisms
- Encapsulation
- Data Abstraction
Demikian sadisnya sehingga orang yang menggunakan atau melihat code yang kita buat, pelan-pelan akhirnya menjadi mengernyitkan dahi..
Kenapa code nya dibuat seperti ini ?
Code seperti ini membuat fleksibilitas nya kurang..
dll..
Lalu ?
Lalu muncullah prinsip SOLID diatas, yang mendorong para Software Engineer lebih beradab dalam mendesain dan memanfaatkan fitur Object Oriented tersebut.
SOLID Principle yang ada 5 :
- Single Object responsibility Principle.
- Open Close Principle.
- Liskov Subtitution Principle.
- Interface Segregation Principle.
- Dependency Injection Principle.
Prinsip-prinsip diatas menjadi pondasi dasar ketika kita ingin melakukan programming dengan konsep OOP.
Yang kemudian populer diperkenalkan oleh Robert C. Martin pada tahun 2000 didalam makalah berjudul “Design Principles and Design Patterns.”
Dan guess what ?
bahwa Abstraksi memegang peranan penting dalam prinsip-prinsip diatas.
Yaitu kita berfokus kepada Class Abstrak nya atau Class Interface nya.
Karena disanalah letak Kontrak Desain yang kita rancang.
Class-class implementasinya harus mengikuti standar dari class Abstract dan class Interfacenya.
Namanya juga Prinsip Desain, maka tentunya kebanyakan kita akan berkutat dengan Kontrak Desain
Nah salah satu prinsip yang terkait dengan Abstraksi diatas adalah :
Liskov Substitution PrincipleTentang Abstraksi dapat dilihat di sini
Liskov Subtitution Principle
Liskov Subtitution Principle adalah prinsip terkait dengan hubungan antara Class Parent dan Class Child dalam inheritance.
Diperkenalkan oleh Barbara Liskov pada tahun 1987, seorang Ilmuwan Komputer dari Amerika.
Yang pada tahun 2010 juga dianugrahi Turing Award karena dedikasinya.
Prinsip Liskov Subtitution Principle ini disampaikan pada saat beliau menjadi keynote speaker di Konferensi Data Abstraction and Hierarchy
Prinsip ini berdasarkan prinsip awal dari Object Oriented Programming yang menyatakan :
Sebuah Object dapat digantikan dengan sub-object (oleh class childnya) tanpa membuat programnya gagal.
Sebuah prinsip yang wajar saja sebenarnya..
Dan Liskov Substitution Principle ini menambah teorinya lagi dengan konsep :
Strong Behaviour Subtype, yaitu ketika sebuah sub-object menggantikan object parentnya, maka behaviour dan kebenaran hasil programmnya tetap terjaga.
Dengan Liskov Substitution Principle ini, maka kita mesti memastikan bahwa :
- Desain Code untuk Object Parent dan Child kita di code memenuhi design by contract, sampai level Behaviour dari object tersebut.
Oleh karenanya dari Liskov Substitution Principle ini kemudian dapat dihubungkan dengan konsep-konsep lainnya, seperti :
- Design by Contract
- Hoare Logic
- Covariant
- Contravariant
- Correctness
- dll
Dengan Liskov Substitution Principle ini, maka kita dituntut selain berfikir Abstrak, sekaligus juga berpikir level implementasi yang rigid.
- Berfikir Abstrak, di level desain , di dalam pikiran kita sebagai Software Engineer.
- Berfikir Implementasi, di level code, menjabarkan detail behaviour. Karena di level compiler tidak bisa menjamin kebenaran behaviour dari child class yang ada.
Jadi Liskov Substitution Principle ini adalah upaya kita dari Software Engineer untuk menjadi “compiler” bagi “Behaviour” dari sub type.
Efeknya apa kalau kita implementasikan Liskov Substitution ini ?
Dengan Liskov Substitution Principle ini, maka kita bisa menjamin bahwa :
- Code client hanya akan berurusan dengan Parent Class nya saja, tidak sampai level implementasi/ Child class nya.
- Kita bisa dengan mudah mengganti Child class/ Class implementationnya, tanpa khawatir dengan kebenaran behaviour dari programnya.
Kenapa perlu ?
Kenapa perlu ?
Hmm.., karena dengan Liskov Substitution Principle ini, maka level pengecekan “Behaviour” dari program yang mempunyai hirarki objek dapat terjamin.
Sehingga kemungkinan Bug dan Keanehan yang terjadi di program client yang memakai hirarki tersebut dapat dicegah.
Apa Contohnya ?
Ok kita coba masuk ke contoh yang sederhana :
- Stack
- Queue
Dua struktur data diatas sepertinya mirip :
- Stack, yaitu struktur data “tumpukan” yang memakai prinsip LIFO (Last In First Out) / Yang terakhir masuk, itu yang pertama kali bisa diambil.
- Queue, yaitu struktur data “antrian” yang memakai prinsip FIFO (First In First Out) / Yang pertama kali masuk, itu yang pertama kali bisa diambil.
Kedua-duanya memiliki fungsi yang semirip :
- put, yaitu untuk meletakkan elemen.
- get, yaitu untuk mengambil elemen.
Di dalam hirarky class Java, kedua struktur data tersebut berbeda. Tidak saling terhubung dengan Inheritance, walaupun sekilas struktur datanya mirip.
Karena kalau dijadikan hirarki Parent Child, maka akan melanggar prinsip Liskov Substitution Principle ini.
Coba kalau kita misalkan menjadikan Stack itu adalah sub type dari Queue.
Dan mengekspose Queue sebagai Parent class nya.
Maka yang terjadi adalah :
- Program Client yang menggunakan class Parent Queue sebagai level abstraksi nya akan mengganggap Stack itu akan mempunyai behaviour seperti deskripsi dari behaviour Queue.
- Program Client berharap akan mendapatkan elemen sesuai dengan FIFO (First In First Out) behaviour.
- Ternyata Stack tidak berperilaku demikian. Tetapi berperilaku LIFO (Last In First Out). Sehingga program client yang menggunakan struktur hirarki diatas bisa saja akan mendapatkan bug dan kesalahan dalam eksekusinya secara keseluruhan.