SOLID — lima prinsip pemrograman berorientasi objek yang dirumuskan oleh Robert C. Martin (Uncle Bob) pada awal tahun 2000-an. Menurut DigitalOcean, 2024, SOLID adalah singkatan dari Single Responsibility, Open-Closed, Liskov Substitution, Interface Segregation dan Dependency Inversion. Prinsip-prinsip ini membentuk dasar Clean Architecture dan diterapkan dalam pengembangan Android (MVP, MVVM, Clean Architecture) dan iOS (VIPER, TCA).
Poin Utama
SOLID — akronim mnemonik yang menunjukkan lima prinsip desain berorientasi objek. Istilah ini diperkenalkan oleh Robert C. Martin dalam artikel “Design Principles and Design Patterns” (2000) dan kemudian dipopulerkan dalam buku “Agile Software Development: Principles, Patterns, and Practices” (2002). SOLID bukan framework atau pustaka — ini adalah kumpulan praktik yang membuat kode lebih sedikit terikat, lebih mudah diuji, dan lebih mudah diubah.
Menurut Clean Coder Blog, 2014, setiap prinsip SOLID memecahkan masalah desain tertentu: SRP melawan God-class, OCP — perubahan berantai, LSP — pewarisan yang salah, ISP — antarmuka gemuk, DIP — pengikatan ketat. Bersama-sama mereka membentuk fondasi Clean Architecture yang digunakan dalam proyek Android dengan MVP, MVVM dan MVI.
Single Responsibility Principle (SRP) — prinsip tanggung jawab tunggal. Rumusan: “Sebuah kelas harus memiliki hanya satu alasan untuk berubah.” Ini berarti setiap modul atau kelas bertanggung jawab tepat untuk satu fungsionalitas atau satu entitas domain. Jika sebuah kelas mengelola pengguna dan juga mengirim email — ia memiliki dua alasan untuk berubah, yang melanggar SRP.
Menurut Robert C. Martin, 2002, SRP adalah prinsip terpenting sekaligus yang paling sering dilanggar. Dalam pengembangan mobile, SRP sering dilanggar di Activity/Fragment, menggabungkan logika UI, navigasi, kerja jaringan dan logika bisnis. Solusinya — pisahkan setiap lapisan ke kelas terpisah: ViewModel untuk logika UI, Repository untuk data, NavController untuk navigasi.
Pertimbangkan kelas UserManager yang memuat profil, menyimpan pengaturan, dan mengirim email. Ini tiga tanggung jawab berbeda, masing-masing harus dipisahkan ke kelas terpisah: UserProfileRepository (pemuatan), UserSettingsStorage (penyimpanan) dan EmailService (pengiriman). Kode klien (ViewModel) menggunakan ketiganya melalui Dependency Injection, dan setiap kelas mudah diuji secara terisolasi dan diubah tanpa memengaruhi yang lain.
// ❌ Pelanggaran SRP: Activity tahu tentang jaringan, DB dan UI
class ProfileActivity : AppCompatActivity() {
fun loadProfile() {
api.getUser() // Panggilan jaringan
db.saveUser() // Bekerja dengan DB
updateUI() // Pembaruan UI
}
}
// ✅ SRP dipatuhi: lapisan terpisah
class ProfileViewModel : ViewModel() {
private val repo = UserRepository()
fun loadProfile() { repo.getUser() }
}
Tanda pelanggaran SRP: kelas berisi lebih dari 200 baris, memiliki metode dari berbagai bidang, sering berubah karena alasan berbeda. Untuk pengembangan Android aturannya sederhana: Activity hanya bertanggung jawab atas siklus hidup layar, ViewModel — untuk status UI, Repository — untuk sumber data.
Prinsip SRP tidak hanya berlaku untuk kelas, tetapi juga untuk arsitektur tingkat layanan. Setiap mikroservis bertanggung jawab untuk satu entitas domain: UserService — hanya pengguna, PaymentService — hanya pembayaran, NotificationService — hanya notifikasi. Ini memungkinkan penskalaan, deployment, dan pengujian layanan secara independen. Dalam aplikasi mobile, SRP di tingkat mikroservis termanifestasi dalam pembagian klien API berdasarkan domain.
Open-Closed Principle (OCP) — prinsip terbuka/tertutup. Kelas harus terbuka untuk ekstensi (perilaku baru dapat ditambahkan) dan tertutup untuk modifikasi (kode yang ada tidak berubah). Dicapai melalui polimorfisme, kelas abstrak, dan antarmuka. Alih-alih menambahkan if-else ke metode yang ada, implementasi antarmuka baru dibuat.
Menurut Clean Coder Blog, 2014, OCP paling efektif dikombinasikan dengan pola Strategy. Misalnya, jika aplikasi mendukung berbagai metode pembayaran (Google Pay, Apple Pay, PayPal), tidak perlu menambahkan switch-case ke prosesor pembayaran. Setiap metode pembayaran mengimplementasikan antarmuka umum PaymentGateway, dan sistem pembayaran baru ditambahkan sebagai kelas baru tanpa mengubah kode yang ada.
// ✅ OCP: terbuka untuk ekstensi, tertutup untuk modifikasi
interface PaymentGateway {
fun processPayment(amount: Double): Boolean
}
class GooglePayGateway : PaymentGateway {
override fun processPayment(amount: Double) = true
}
// Sistem pembayaran baru — tanpa mengubah kode yang ada
class ApplePayGateway : PaymentGateway {
override fun processPayment(amount: Double) = true
}
Liskov Substitution Principle (LSP) — prinsip substitusi Barbara Liskov. Jika S adalah subtipe dari T, maka objek T dapat digantikan dengan objek S tanpa mengubah properti program. Secara formal: fungsi yang menggunakan kelas dasar harus bekerja dengan benar dengan subkelas mana pun. Jika subkelas melempar exception di mana kelas dasar tidak — LSP dilanggar.
Menurut Robert C. Martin, 2002, LSP adalah prinsip SOLID yang paling sulit dipahami. Contoh klasik pelanggaran — kelas Square (persegi) yang mewarisi Rectangle (persegi panjang). Jika setWidth untuk Square mengatur lebar dan tinggi, kode klien yang mengharapkan perilaku Rectangle akan mendapatkan hasil tak terduga. Dalam pengembangan mobile, LSP sering dilanggar saat pewarisan ViewModel, ketika ViewModel anak menambahkan dependensi wajib.
// ❌ Pelanggaran LSP: Square merusak perilaku Rectangle
open class Rectangle(open var width: Int, open var height: Int)
class Square(side: Int) : Rectangle(side, side) {
override var width
get() = super.width
set(value) { super.setBoth(value, value) }
}
Interface Segregation Principle (ISP) — prinsip segregasi antarmuka. Klien tidak boleh bergantung pada antarmuka yang tidak mereka gunakan. Alih-alih satu antarmuka “gemuk”, buat beberapa antarmuka sempit yang terspesialisasi. Jika sebuah kelas mengimplementasikan antarmuka tetapi sebagian metodenya melempar UnsupportedOperationException atau kosong — ini tanda jelas pelanggaran ISP.
Menurut DigitalOcean, 2024, ISP sangat relevan dalam pengembangan mobile saat mendesain ViewModel dan Repository. Alih-alih satu antarmuka UserRepository dengan semua metode CRUD, lebih baik buat QueryUserRepository (hanya baca) dan CommandUserRepository (tulis). Maka klien pembaca (elemen UI) hanya bergantung pada antarmuka Query dan tidak tahu tentang metode tulis.
// ❌ Antarmuka gemuk — klien dipaksa mengimplementasikan metode tidak perlu
interface UserOperations {
fun getUser(id: String): User
fun saveUser(user: User)
fun deleteUser(id: String)
fun exportUsers(): File
}
// ✅ ISP: antarmuka terpisah
interface UserReader { fun getUser(id: String): User }
interface UserWriter { fun saveUser(user: User) }
interface UserDeleter { fun deleteUser(id: String) }
Dependency Inversion Principle (DIP) — prinsip inversi dependensi. Modul tingkat tinggi tidak boleh bergantung pada modul tingkat rendah. Kedua level harus bergantung pada abstraksi (antarmuka). Abstraksi tidak boleh bergantung pada detail — detail bergantung pada abstraksi. Ini tidak sama dengan “Dependency Injection” (DI), meskipun DI adalah cara umum untuk mengimplementasikan DIP.
Menurut Robert C. Martin, 2019, DIP adalah dasar Clean Architecture. ViewModel (tingkat tinggi) tidak boleh langsung membuat instance RetrofitApi (detail). Sebaliknya, ViewModel bergantung pada antarmuka UserRepository, dan implementasi konkret UserRepositoryImpl dengan Retrofit diteruskan melalui konstruktor. Di Android, DIP diimplementasikan melalui Hilt/Dagger atau Koin: semua dependensi disediakan melalui kontainer DI.
// ✅ DIP: Modul bergantung pada abstraksi, bukan detail
class UserRepositoryImpl(
private val api: UserApi, // Bergantung pada antarmuka
private val db: UserDao // Bergantung pada antarmuka
) : UserRepository {
override suspend fun getUser(id: String): User {
return api.fetchUser(id)
}
}
// Hilt DI: detail dihubungkan melalui modul DI
@Module
object NetworkModule {
@Provides
fun provideUserApi(retrofit: Retrofit): UserApi =
retrofit.create(UserApi::class.java)
}
SOLID dalam pengembangan mobile diterapkan di semua level: dari arsitektur aplikasi hingga kelas individual. Dalam proyek Android, Clean Architecture membagi kode menjadi tiga lapisan: domain (logika bisnis — independen dari framework), data (repositori, API, DB) dan presentation (UI, ViewModel). Lapisan domain menggunakan prinsip SOLID: use case (SRP), antarmuka repositori (DIP), kelas entitas (OCP + LSP).
Menurut Android Developers Guide, 2025, SRP di Android termanifestasi dalam pembagian ViewModel, Repository dan Mapper. OCP — saat menambahkan sumber data baru melalui antarmuka DataSource. LSP — dalam pemrosesan seragam Result dari repositori berbeda. ISP — dalam pendekatan CQRS (pemisahan repositori Read/Write). DIP — melalui Hilt/Koin untuk injeksi dependensi.
| Prinsip | Masalah tanpanya | Solusi di proyek mobile |
|---|---|---|
| SRP | Activity 1000+ baris | ViewModel + UseCase + Repository |
| OCP | switch-case per jenis pembayaran | Strategy: antarmuka PaymentGateway |
| LSP | Bug saat mengganti BaseViewModel | Pemeriksaan kontrak subkelas |
| ISP | UnsupportedOperationException | Pemisahan Reader / Writer |
| DIP | ViewModel membuat Retrofit manual | Kontainer DI Hilt / Koin |
Kesalahan SOLID paling sering terkait dengan komplikasi kode yang berlebihan. Pertama — mengikuti prinsip secara harfiah tanpa mempertimbangkan konteks. Membagi satu kelas UserService menjadi 10 antarmuka dan 15 kelas demi ISP “bersih” adalah overengineering. SOLID adalah alat, bukan tujuan. Kesalahan kedua — kebingungan antara SRP dan “satu metode = satu tanggung jawab”. Sebuah kelas dapat memiliki banyak metode, jika semuanya termasuk dalam satu area tanggung jawab.
Menurut Simple Thread, 2024, kesalahan ketiga — mengabaikan LSP saat pewarisan ViewModel di Android. Jika ViewModel dasar mengharapkan LiveData dan anak menggunakan StateFlow — kode klien yang berlangganan LiveData tidak akan menerima pembaruan. Keempat — pelanggaran DIP demi pengujian: RepositoryImpl langsung membuat instance OkHttpClient, yang membuat pengujian unit tidak mungkin.
Aturan emas: terapkan SOLID ketika memecahkan masalah nyata (sering berubah, sulit diuji, duplikasi). Untuk layar CRUD sederhana, kepatuhan ketat terhadap kelima prinsip berlebihan. Untuk logika bisnis, perhitungan keuangan, dan interaksi API, SOLID wajib.
Clean Architecture (Robert C. Martin, 2012) — penerapan langsung SOLID di tingkat lapisan aplikasi. SRP menentukan batas use case (setiap use case — satu kelas). OCP diimplementasikan melalui antarmuka repositori (lapisan Data dapat berubah tanpa mengubah Domain). ISP memberikan pemisahan Use Case menjadi boundary input/output. DIP — arah dependensi ke dalam lapisan Domain. LSP menjamin bahwa setiap implementasi repositori dapat diganti tanpa merusak use case.
Pertanyaan yang Sering Diajukan
SOLID — lima aturan menulis kode agar mudah diubah, diuji, dan dipahami. Setiap huruf adalah satu prinsip: jangan menulis kelas besar (SRP), jangan mengubah kode yang ada — tambahkan yang baru (OCP), jangan merusak perilaku pewaris (LSP) dan lainnya.
SRP (Single Responsibility) dianggap paling penting karena pelanggarannya menyebabkan God-class — kelas besar yang sulit diuji dan diubah. Namun tanpa DIP (Dependency Inversion) kode tetap terikat ketat, yang juga kritis.
Tidak wajib, tetapi sangat disarankan untuk proyek komersial dengan siklus hidup panjang. Untuk aplikasi sederhana (satu layar, tanpa logika bisnis) SOLID bisa berlebihan. Untuk proyek dengan 50+ layar dan 3+ pengembang, SOLID adalah minimum yang diperlukan.
Konsekuensi: kelas menjadi “gemuk” (1000+ baris), perubahan di satu tempat merusak tiga lainnya, tidak mungkin menulis pengujian unit, menambahkan fitur baru memakan waktu berminggu-minggu. Seiring waktu, kode berubah menjadi “Big Ball of Mud” — kusut dan rapuh.
Tanda kepatuhan: setiap kelas kurang dari 200 baris, perubahan fitur tidak memengaruhi 5+ file, pengujian ditulis tanpa mock 10 dependensi, pengembang baru memahami struktur dalam sehari. Alat seperti SonarQube dan detekt membantu mendeteksi pelanggaran SRP dan DIP.
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