Hola.. hola.. hola..!! Selamat datang kembali di Blog Sandi Dharma. Gimana kabarnya hari ini? Tentu Tetap semangat dong 😎
Pada kesempatan ini kita akan berkenalan dengan salah satu prinsip yang sangat terkenal di dunia perkodingan Ialah SOLID Principle. Apa itu SOLID Principle? Apa gunanya? Mmm, daripada menerka-nerka, yuk kita mulai aja.
SOLID Principle
SOLID Principle adalah sebuah akronim dari 5 prinsip Object Oriented Design (OOD). Prinsip ini diperkenalkan oleh Robert C. Martin (juga dikenal sebagai Uncle Bob).
Prinsip ini memberikan praktik yang cocok Demi mengembangkan software dengan pertimbangan agar mudah Demi dipertahankan (maintain) dan dikembangkan seiring dengan pertumbuhan proyek aplikasi.
SOLID mewakili 5 buah prinsip sebagai berikut:
- S – Single-responsibility Principle
- O – Open-closed Principle
- L – Liskov Subtitution Principle
- I – Interface Segregation Principle
- D – Dependency Inversion Principle
Pada tulisan ini kita akan belajar memahami Serempak-sama bagaimana SOLID Principle dapat membantu kita Demi mengembangkan software yang Berkualitas.
Single-Responsibility Principle (SRP)
There should never be more than one reason for a class to change.
Single-responsibility Principle (SRP) merupakan salah prinsip yang terbilang cukup mudah Demi kita terapkan dalam mengembangkan software. Sederhananya, prinsip ini mengatur tanggung jawab (responsibility) sebuah entitas/class. Dalam prinsip ini, sebuah entitas/class Sepatutnya hanya Mempunyai satu buah tanggung jawab. Apabila Terdapat sebuah entitas/class yang Mempunyai dua tanggung jawab yang sama sekali Enggak Mempunyai keterkaitan, maka kita harus memisahkannya menjadi dua buah entitas/class yang berbeda.
Demi lebih memahami prinsip ini, coba Engkau perhatikan Misalnya kode berikut:
Note: Misalnya menggunakan bahasa Python
class Item:
...
class Order:
def add_item(Item):
...
def delete_item(Item):
...
def get_daily_order_history():
...
def get_monthly_order_history():
...
Dari Misalnya kode tersebut, class Order Mempunyai 2 tanggung jawab Ialah mengelola item dalam order dan order history. Tentu hal ini Enggak sesuai dengan prinsip SRP. Dengan menerapkan prinsip SRP, kita Dapat memisahkan tanggung jawab yang Terdapat pada class Order. Perhatikan Misalnya berikut.
Note: Misalnya menggunakan bahasa Python
class Item:
...
class Order:
def add_item(Item):
...
def delete_item(Item):
...
class OrderHistory:
def get_daily_history():
...
def get_monthly_history():
...
Open-Closed Principle (OCP)
Software entities … should be open for extension, but closed for modification.
Open-Closed Principle (OCP) menjelaskan bahwa sebuah entitas/class dapat terbuka Demi ditambahkan tetapi tertutup Demi dimodifikasi. Secara sederhana, sebuah entitas/class Sepatutnya dapat dengan mudah Demi dikembangkan sesuai dengan kebutuhan Tetapi tanpa memodifikasi entitas/class tersebut.
OCP dapat diterapkan dengan memanfaatkan interface dan kelas abstrak. Interface dan abstraksi kelas ini bertujuan Demi mempermudah perbaikan atau penambahan fitur setelah pengembangan selesai tanpa harus memodifikasi entitas/class yang sudah Terdapat. Jadi, dengan menggunakan interface atau abstrak, kita cukup Membangun sebuah kelas baru yang mewarisi interface atau abstrak kelasnya ketika Ingin menambahkan fungsionalitas baru.
Note: Misalnya menggunakan bahasa PHP
Interface Cache
php
interface Cache
{
public function set($key, $value);
public function get($key);
public function delete($key);
}
Cache menggunkan file
php
class FileCache implements Cache {
public function set($key, $value)
{
...
}
public function get($key)
{
...
}
public function delete($key)
{
...
}
}
Cache menggunakan redis
php
class RedisCache implements Cache {
public function set($key, $value)
{
...
}
public function get($key)
{
...
}
public function delete($key)
{
...
}
}
Dari Misalnya kode tersebut, kita Mempunyai sebuah interface Cache yang didalamnya terdapat method-method Demi mengelola cache. Interface tersebut kemudian diimplementasikan pada kelas FileCache. Berikutnya, anggap saja suatu Begitu kita Ingin menggunakan driver cache lainnya seperti redis. Kita cukup Membangun kelas baru bernama RedisCache yang tetap mengimplementasikan interface Cache. Dengan Langkah seperti ini, kita Enggak perlu merubah kode pada kelas FileCache yang sebelumnya sudah kita buat.
Liskov Substitution Principle (LSP)
Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.
Secara sederhana, prinsip ini berlaku pada hirarki pewarisan sifat yang Terdapat pada OOP. Pada prinsip ini, seluruh subclass harus dapat berjalan dengan Langkah yang sama seperti superclass-nya.
Ketika kita Membangun sebuah subclass, selain harus menerapkan fungsi dan properti dari superclas, subclass juga harus Mempunyai perilaku yang sama seperti superclass-nya. Terdapat beberpa aturan yang harus dipatuhi Demi mencapai hal ini, diantaranya adalah sebagai berikut.
Contravariant dan Covariant
Contravariant adalah konversi kelas dari sub kelasnya ke kelas yang lebih tinggi hierarkinya. Sedangkan covariant adalah kebalikan dari konversi. Itu mengkonversi dari kelas tinggi dalam hierarki ke yang lebih spesifik.
Preconditions dan Postconditions
Preconditions adalah aturan yang harus Terdapat sebelum tindakan dilakukan. Misalnya, sebelum memanggil method yang membaca data dari database, sebuah kelas perlu memenuhi prasyarat bahwa koneksi database telah terbuka. Sedangkan postconditions menggambarkan keadaan kelas setelah proses selesai.
Invariant
Invariant menggambarkan kondisi proses yang Betul sebelum proses dimulai dan tetap Betul setelahnya. Misalnya, kelas mungkin menyertakan method yang membaca teks dari file. Apabila method menangani pembukaan dan penutupan file, invarian adalah kemungkinan bahwa file Enggak dibuka sebelum pemanggilan atau sesudahnya. Demi mematuhi LSP, invarian dari kelas dasar Enggak boleh diubah oleh subkelas.
Constraint
Berdasarkan sifatnya, subclass mencakup Sekalian metode dan properti dari superclass-nya. Mereka juga dapat menambahkan properti lainnya. Constraint mengatur agar bahwa properti baru atau yang dimodifikasi Enggak boleh mengubah status objek dengan Langkah yang Enggak diizinkan oleh superclass.
Demi lebih memahami prinsip LSP, perhatikan Misalnya kode berikut.
Note: Misalnya menggunakan bahasa PHP
php
abstract Product
{
public function getName()
{
throw new Error("Method not implemented");
}
}
class Electronic extends Product
{
public function getName()
{
return "Electronic Product";
}
}
class SmartPhone extends Electronic
{
public function getName()
{
return "SmartPhone Product";
}
public function getConnectifity()
{
return "5G";
}
}
class Food extends Product
{
public function getName()
{
return "Food Product";
}
public function getExpiryDate()
{
return date('Y-m-d');
}
}
Dari Misalnya kode di atas, kita Mempunyai sebuah abstract Product yang Mempunyai satu method Ialah getName. Kemudian terdapat kelas Electronic yang meng-extends abstract Product. Berikutnya, kita juga Mempunyai kelas SmartPhone yang meng-extends kelas Electronic, di dalam kelas ini terdapat method tambahan Ialah getConnectivity. Kenapa kita menamhahkan method ini di kelas SmartPhone? Karena agar kelas Electronic tetap dapat diturunkan ke kelas Electronic lainnya yang Enggak Mempunyai konektivitas, misalnya Kipas angin.
Begitu juga dengan kelas Food yang meng-extends abstract Product, disitu kita menambahkan method getExpiryDate karena produk lainnya Enggak Mempunyai Copot kadaluarsa.
Interface Segregation Principle (ISP)
Clients should not be forced to depend upon interfaces that they do not use.
Prinsip ini bertujuan Demi mengurangi dan membatasi jumlah ketergantungan sebuah kelas terhadap interface yang Enggak diperlukan. Begitu Membangun sebuah interface, sebaiknya kita membuatnya sebagai bagian yang lebih kecil dan lebih spesifik fungsinya. Sehingga, ketika kita membutuhkannya pada kelas lain, kita Enggak perlu mengimplementasikan Sekalian method yang sebenarnya Enggak kita gunakan pada kelas yang kita buat.
Demi lebih memahaminya, perhatikan Misalnya kode berikut:
Note: Misalnya menggunakan bahasa PHP
php
interface Authenticatable
{
public function login();
}
interface Notifiable
{
public function notify();
}
class Admin implements Authenticatable, Notifiable
{
public function login()
{
...
}
public function notify()
{
...
}
}
class Subscriber implements Notifiable
{
public function notify()
{
...
}
}
Berdasarkan Misalnya tersebut, kita Mempunyai dua buah interface Ialah Authenticatable dan Notifiable. Pada kelas Admin, kita mengimplementasikan kedua interface. Sedangkan pada kelas Subscriber, kita hanya mengimplementasikan interface Notifiable agar dapat mengirimkan notifikasi, misalnya menggunakan email subscription. Dengan Langkah ini, kelas Subscriber Enggak dipaksa Demi mengimplementasikan interface Authenticatable yang sebenarnya Enggak diperlukan.
Dependency Inversion Principle (DIP)
High-level modules should not depend on low-level modules. Both should depend on abstractions.
Prinsip ini Nyaris sama dengan konsep layering dalam sebuah aplikasi. Low-level modules bertanggung jawab dengan fungsi yang sangat detail dan high-level modules menggunakan low-level classes Demi mencapai tugas yang lebih besar. Hal ini Dapat dicapai dengan bergantung pada sebuah abstraksi, ketika Terdapat ketergantungan antar kelas seperti interface, daripada Surat keterangan langsung ke kelas lainnya.
Perhatikan Misalnya berikut ini:
Note: Misalnya menggunakan bahasa Kotlin
Membangun interface
interface EngineInterface {
fun start()
}
Membangun kelas Boat
class Boat(private val engine: EngineInterface) {
fun start() {
engine.start()
}
}
Membangun kelas jenis-jenis Engine
class PetrolEngine : EngineInterface {
override fun start() {}
}
class DieselEngine : EngineInterface {
override fun start() {}
}
Membangun beberapa Boat dengan Engine yang berbeda hanya dengan menggunakan base class Boat yang sama.
fun main() {
val petrolEngine = PetrolEngine()
val petrolBoat = Boat(petrolEngine)
val dieselEngine = DieselEngine()
val dieselBoat = Boat(dieselEngine)
petrolBoat.start()
dieselBoat.start()
}
Menerapkan prinsip Dependency Inversion Membangun kita lebih Elastis dalam membangun sistem.
Sumber: