SOLID: prinsip, 5 aturan OOP dan penerapan dalam pengembangan

Penulis: IT Sectr Diterbitkan: 2026-05-11 Waktu membaca: 10 mnt

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 lima prinsip OOP: SRP, OCP, LSP, ISP, DIP, dirumuskan oleh Robert C. Martin untuk membuat kode yang fleksibel dan mudah dipelihara.
  • SRP (Single Responsibility) — setiap kelas memiliki satu alasan untuk berubah, satu tanggung jawab per modul.
  • OCP (Open-Closed) — kelas terbuka untuk ekstensi tetapi tertutup untuk modifikasi, diimplementasikan melalui pewarisan dan polimorfisme.
  • LSP (Liskov Substitution) — objek subkelas harus dapat menggantikan objek kelas dasar tanpa mengubah kebenaran program.
  • ISP (Interface Segregation) — klien tidak boleh bergantung pada antarmuka yang tidak mereka gunakan, antarmuka harus sempit dan spesifik.
  • DIP (Dependency Inversion) — modul tingkat tinggi tidak bergantung pada modul tingkat rendah, keduanya bergantung pada abstraksi.

Apa itu SOLID? Ikhtisar lima prinsip

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.

SRP: Single Responsibility Principle

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.

Contoh SRP: pembagian UserManager

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.

kotlin
// ❌ 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.

SRP dan arsitektur mikroservis

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.

OCP: Open-Closed Principle

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.

kotlin
// ✅ 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
}

LSP: Liskov Substitution Principle

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.

kotlin
// ❌ 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) }
}

ISP: Interface Segregation Principle

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.

kotlin
// ❌ 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) }

DIP: Dependency Inversion Principle

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.

kotlin
// ✅ 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)
}

Penerapan SOLID dalam pengembangan mobile

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.

PrinsipMasalah tanpanyaSolusi di proyek mobile
SRPActivity 1000+ barisViewModel + UseCase + Repository
OCPswitch-case per jenis pembayaranStrategy: antarmuka PaymentGateway
LSPBug saat mengganti BaseViewModelPemeriksaan kontrak subkelas
ISPUnsupportedOperationExceptionPemisahan Reader / Writer
DIPViewModel membuat Retrofit manualKontainer DI Hilt / Koin

Kesalahan umum saat menerapkan SOLID

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.

Hubungan SOLID dan Clean Architecture

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

Apa itu SOLID dengan kata sederhana?

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.

Prinsip SOLID mana yang paling penting?

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.

Apakah SOLID wajib untuk pengembangan mobile?

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.

Apa yang terjadi jika tidak mematuhi SOLID?

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.

Bagaimana memeriksa apakah SOLID dipatuhi di proyek?

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

  • SOLID — lima prinsip OOP (SRP, OCP, LSP, ISP, DIP) untuk kode yang fleksibel dan mudah dipelihara
  • SRP — setiap entitas bertanggung jawab untuk satu tugas, memecahkan masalah God-class
  • OCP — ekstensi melalui polimorfisme, bukan modifikasi kode yang ada
  • LSP — pewaris tidak boleh merusak perilaku kelas dasar
  • ISP — antarmuka sempit alih-alih “pisau Swiss” universal
  • DIP — ketergantungan pada abstraksi, injeksi melalui Hilt/Koin di Android
  • SOLID wajib untuk Clean Architecture dan proyek mobile komersial

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.

Diskusikan proyek

Baca juga