OCP (Open/Closed Principle) — prinsip SOLID kedua yang menentukan: entitas perangkat lunak harus terbuka untuk ekstensi, tetapi tertutup untuk modifikasi. Prinsip ini, dirumuskan oleh Bertrand Meyer pada tahun 1988, memungkinkan penambahan fungsionalitas baru tanpa mengubah kode yang ada. Menurut buku Robert C. Martin Clean Architecture (2017), prinsip keterbukaan diimplementasikan melalui abstraksi dan polimorfisme, meminimalkan risiko kesalahan regresi.
Poin Utama
OCP (Open/Closed Principle) — prinsip keterbukaan untuk ekstensi dan ketertutupan untuk modifikasi. Kelas, modul, dan fungsi harus dirancang sedemikian rupa sehingga perilaku baru dapat ditambahkan tanpa mengubah kode sumber mereka. Ekstensi dicapai melalui pewarisan, komposisi, atau substitusi implementasi antarmuka.
Bertrand Meyer dalam buku Object-Oriented Software Construction (1988) pertama kali mendeskripsikan OCP melalui pewarisan: kelas dasar tetap tidak berubah, dan subkelas memperluas perilakunya. Interpretasi modern OCP, yang diusulkan oleh Robert C. Martin, didasarkan pada polimorfisme dan antarmuka: alih-alih pewarisan, kontrak abstrak digunakan.
Perbedaan antara pendekatan tersebut signifikan. Pewarisan menciptakan ikatan kaku antara kelas dasar dan turunan. Antarmuka dan komposisi memberikan fleksibilitas: implementasi diganti tanpa mengubah kode klien. OCP modern — tentang abstraksi, bukan pewarisan.
OCP polimorfik menggunakan kelas abstrak atau antarmuka untuk mendefinisikan kontrak. Kode klien bekerja dengan abstraksi, tanpa mengetahui implementasi konkret. Fungsionalitas baru ditambahkan dengan membuat kelas baru yang mengimplementasikan antarmuka yang sama — tanpa perubahan apa pun pada kode yang ada. Ini membuat sistem tahan terhadap perubahan dan dapat diprediksi untuk ekstensi.
Dalam pengembangan mobile, pendekatan ini ada di mana-mana: pola Strategy memungkinkan penggantian algoritma (kompresi gambar, caching, autentikasi) melalui antarmuka bersama. Penambahan strategi baru tidak memerlukan perubahan kode yang menggunakannya.
Implementasi OCP dimulai dengan memisahkan perilaku variabel ke dalam abstraksi. Jika dalam kode terdapat konstruksi switch atau rantai if-else yang memeriksa tipe objek — ini adalah sinyal untuk menerapkan OCP. Setiap cabang kondisi berpotensi memerlukan penambahan cabang baru saat ekstensi.
Proses refactoring sesuai OCP mencakup tiga langkah: mengidentifikasi aspek variabel (apa yang dapat diperluas), memisahkannya ke dalam antarmuka atau kelas abstrak, menulis ulang kode klien untuk bekerja dengan abstraksi alih-alih kelas konkret. Setelah itu, fungsionalitas baru ditambahkan tanpa mengubah klien.
Catatan penting: ketertutupan untuk modifikasi tidak mutlak. Jika persyaratan perubahan menyangkut abstraksi itu sendiri atau kontrak — perubahan tidak dapat dihindari. OCP melindungi dari perubahan dalam implementasi, bukan dalam kontrak. Desain yang baik mengasumsikan bahwa kontrak stabil dan implementasi variabel.
Saat mengevaluasi kompatibilitas arsitektur dengan OCP, berguna untuk melihat titik ekstensi. Setiap titik di mana pengembang menambahkan if-else atau switch untuk tipe baru — kandidat untuk abstraksi. Sistem yang dirancang sesuai OCP memiliki titik ekstensi yang dapat diprediksi: antarmuka dengan dokumentasi “implementasikan antarmuka ini untuk menambahkan tipe baru”. Di Android, contohnya adalah pola Factory bersama dengan ViewModelProvider.Factory — penambahan tipe ViewModel baru tidak memerlukan perubahan pabrik yang ada.
Pola paling efektif untuk mematuhi OCP dalam pengembangan mobile mencakup Strategy, Template Method, Decorator, dan Factory. Masing-masing memecahkan masalah perluasan perilaku tanpa mengubah kode yang ada melalui mekanisme desain berorientasi objek yang berbeda.
Strategy memungkinkan penggantian algoritma dengan cepat melalui antarmuka bersama. Dalam pengembangan iOS, strategi digunakan untuk animasi dan validasi formulir. Template Method mendefinisikan kerangka algoritma di kelas dasar, dan subkelas menimpa langkah-langkahnya — cocok untuk layar dengan struktur umum tetapi konten berbeda.
Decorator secara dinamis menambahkan perilaku ke objek tanpa mengubah kelasnya. Di Android, Decorator diterapkan untuk membungkus Repository dengan lapisan cache atau logging. Factory Method membuat objek melalui antarmuka, memungkinkan subkelas memutuskan kelas mana yang akan diinstansiasi — dasar pembuatan ketergantungan yang kompatibel dengan OCP.
Pemilihan pola tergantung pada stabilitas perilaku yang diperluas. Strategy optimal ketika algoritma diganti sepenuhnya. Template Method — ketika struktur tetap tetapi langkah-langkah variabel. Decorator — ketika ekstensi harus transparan bagi klien. Untuk sebagian besar skenario di Android dan iOS, Strategy + injeksi ketergantungan sudah cukup.
Menerapkan pola-pola ini tanpa OCP secara teknis mungkin, tetapi kehilangan maknanya. Justru OCP yang membenarkan mengapa kita memperkenalkan tingkat abstraksi tambahan: agar sistem dapat tumbuh tanpa menulis ulang kode yang ada.
Mari kita lihat contoh Android dengan pemrosesan pembayaran. Tanpa OCP, setiap sistem pembayaran baru memerlukan perubahan kelas pemroses. Dengan OCP, implementasi antarmuka baru ditambahkan tanpa mengedit kode yang ada.
// Pelanggaran OCP: switch memerlukan perubahan untuk sistem baru
class BadPaymentProcessor {
fun process(type: String) {
when (type) {
"card" -> // pemrosesan kartu
"paypal" -> // pemrosesan PayPal
}
}
}
// Desain kompatibel dengan OCP
interface PaymentMethod {
fun pay(amount: Double)
}
class CardPayment : PaymentMethod {
override fun pay(amount: Double) { }
}
class PayPalPayment : PaymentMethod {
override fun pay(amount: Double) { }
}
// Sistem baru — kelas baru, tanpa mengubah kode yang ada
class ApplePayPayment : PaymentMethod {
override fun pay(amount: Double) { }
}
Contoh iOS dengan validasi bidang teks menunjukkan logika yang sama melalui protokol Swift:
// Validasi kompatibel dengan OCP
protocol ValidationRule {
func validate(_ input: String) -> Bool
}
struct EmailRule: ValidationRule {
func validate(_ input: String) -> Bool {
return input.contains("@")
}
}
struct PhoneRule: ValidationRule {
func validate(_ input: String) -> Bool {
return input.count == 11
}
}
// Penambahan aturan baru tidak memerlukan perubahan kode validator
struct PasswordRule: ValidationRule {
func validate(_ input: String) -> Bool {
return input.count >= 8
}
}
Keuntungan utama OCP dalam contoh ini: penambahan ApplePay atau PasswordRule tidak memerlukan perubahan kelas yang ada. Kode meluas secara horizontal — melalui file baru, bukan dengan mengubah file lama. Ini mengurangi risiko regresi dan mempercepat implementasi fungsionalitas baru.
Pelanggaran paling umum — konstruksi switch atau when berdasarkan tipe objek. Setiap kali tipe baru ditambahkan, semua switch tersebut harus ditemukan dalam kode dan cabang baru ditambahkan. Switch yang terlewat — kesalahan runtime yang sulit dideteksi pada tahap kompilasi.
Dalam pengembangan mobile, OCP dilanggar saat menggunakan kelas enum raksasa dengan metode yang bergantung pada nilai enum. Penambahan elemen enum baru memerlukan perubahan setiap switch di seluruh proyek. Alternatifnya — polimorfisme melalui antarmuka, di mana setiap tipe mengimplementasikan perilakunya sendiri.
Pelanggaran umum lainnya — God Adapter: RecyclerView.Adapter (Android) atau UITableViewDataSource (iOS) yang memproses berbagai tipe sel melalui if-else. Setiap tipe sel baru memerlukan perluasan adapter. Solusinya — ViewHolder polimorfik dengan metode bind bersama, di mana setiap tipe sel bertanggung jawab atas tampilannya sendiri.
Tindakan pencegahan meliputi: meninggalkan switch berdasarkan tipe demi polimorfisme, injeksi ketergantungan melalui antarmuka, dan penerapan pola Factory untuk membuat objek berdasarkan konfigurasi. Analisis kode untuk “sakelar berdasarkan tipe” — bagian wajib dari code review di tim yang berorientasi OCP.
Refactoring pelanggaran OCP yang ada dilakukan melalui Replace Conditional with Polymorphism: setiap cabang kondisi menjadi kelas terpisah dengan implementasi antarmuka bersama. Kode klien ditulis ulang untuk bekerja dengan antarmuka, dan implementasi konkret disediakan melalui pabrik atau wadah DI.
Penting untuk dipahami bahwa OCP dan polimorfisme tidak menyelesaikan semua masalah ekstensi. Jika arsitektur dipilih secara tidak tepat, penambahan fungsionalitas baru akan memerlukan perubahan tidak hanya implementasi tetapi juga kontrak. Arsitektur yang baik memprediksi arah ekstensi dan menempatkan abstraksi tepat di titik-titik tersebut. Investasi dalam OCP semakin terbayar semakin lama proyek bertahan dan semakin sering persyaratan untuk modul tertentu berubah.
Pertanyaan yang Sering Diajukan
Tidak. OCP melarang perubahan kode yang ada saat menambahkan fungsionalitas baru yang termasuk dalam abstraksi yang sama. Perubahan kontrak, perbaikan bug, dan refactoring bukanlah pelanggaran OCP — prinsip ini melindungi dari perubahan berantai saat ekstensi.
Strategy — implementasi langsung dari OCP. Antarmuka strategi mendefinisikan kontrak, klien bergantung pada abstraksi, dan strategi konkret mengimplementasikan perilaku variabel. Penambahan strategi baru tidak memerlukan perubahan klien — ini adalah keterbukaan untuk ekstensi dengan ketertutupan untuk modifikasi.
Ya, melalui pewarisan dan Template Method: kelas dasar mendefinisikan kerangka algoritma, subkelas menimpa langkah-langkahnya. Namun, pewarisan menciptakan ikatan kaku dan kurang fleksibel dibandingkan antarmuka. Dalam pengembangan modern, antarmuka dan komposisi dianggap sebagai cara yang lebih disukai untuk mengimplementasikan OCP.
Kode yang kompatibel dengan OCP menyederhanakan pengujian: setiap implementasi antarmuka diuji secara terisolasi. Kode klien diuji dengan implementasi mock, yang memungkinkan verifikasi logika tanpa terikat pada perilaku spesifik. Perluasan sistem tidak memerlukan penulisan ulang pengujian yang ada.
Tidak. OCP dibenarkan ketika perluasan fungsionalitas dapat diprediksi. Untuk kode stabil yang tidak direncanakan untuk diperluas, abstraksi tambahan berlebihan. YAGNI (You Ain't Gonna Need It) — penyeimbang yang baik untuk OCP: abstraksi diperkenalkan ketika varian perilaku kedua muncul, bukan sebelumnya.
Kesimpulan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga