Tiga belas chapter sejak Memahami Class dan Object membangun kotak peralatan OOP yang lengkap — dan sekarang tibalah pertanyaan yang memisahkan programer berpengalaman dari yang bukan: kapan peralatan itu memang sebaiknya dipakai? Class bukan tujuan; class adalah alat untuk masalah tertentu. Program Python yang sehat justru penuh fungsi biasa, dan memaksakan class ke masalah yang salah menghasilkan kode yang lebih panjang, lebih lambat dibaca, dan lebih sulit diubah. Chapter penutup Section ini merangkum sinyal-sinyal kapan OOP membayar biayanya, kapan struktur lebih sederhana menang, dan bagaimana menemukan titik tengahnya.
Sinyal OOP Layak Dipakai #
Empat situasi berikut adalah sinyal klasik bahwa class akan menyelesaikan masalah, bukan menambahnya:
- Data hidup bersama aturannya.
Rekeningdari Chapter Encapsulation adalah contohnya: saldo selalu harus lewat pemeriksaansetor()dantarik(). Ketika data punya invarian yang harus dijaga di setiap perubahan, satu wadah berisi data plus method penjaga adalah bentuk paling aman. - Banyak bentuk dari satu interface. Sistem pinjam perpustakaan memproses
Buku,Majalah, dan item lain lewatdurasi_pinjam()yang sama — polymorphism dari Chapter Polymorphism menghapus percabangan tipe dari kode pemanggil. - State harus hidup lintas pemanggilan. Koneksi database, sesi pengguna, game loop — object menyimpan keadaan antar panggilan tanpa meneruskan belasan parameter ke setiap fungsi.
- Ekosistem yang kita tempeli berbasis class. Framework populer di Python (Flask, Django, pytest) menyuruh kita menulis class untuk handler, model, dan test fixture. Tidak menguasai OOP berarti tidak bisa bekerja di ekosistem itu.
Ketika Fungsi dan Dictionary Cukup #
Untuk data yang hanya mengalir — dibaca, diubah, diteruskan — struktur polos sering kali pilihan terbaik:
buku1 = {"judul": "Laskar Pelangi", "penulis": "Andrea Hirata", "tahun": 2005}
buku2 = {"judul": "Bumi Manusia", "penulis": "Pramoedya A. Toer", "tahun": 1980}
def deskripsi(buku):
return f"{buku['judul']} ({buku['tahun']})"
print(deskripsi(buku1))
print(deskripsi(buku2))Output yang Dihasilkan:
Laskar Pelangi (2005)
Bumi Manusia (1980)Tidak ada invarian yang dijaga, tidak ada perilaku berbeda per bentuk — dictionary plus dua fungsi menyelesaikannya dalam sepuluh baris. Kelemahannya juga jujur terlihat: key dictionary bebas salah ketik (typo judul baru ketahuan sebagai KeyError saat program berjalan), dan bentuk datanya tidak tertulis di satu tempat. Ketika kelemahan itu mulai terasa mengganggu, jangan langsung lompat ke class penuh — Python punya jalan tengahnya.
Dataclasses untuk Data Murni #
Bentuk data yang perlu dideklarasikan, tetapi tidak butuh method penjaga, pas dengan @dataclass: decorator yang otomatis menghasilkan __init__, __repr__, dan perbandingan kesetaraan dari deklarasi field:
from dataclasses import dataclass
@dataclass
class Buku:
judul: str
penulis: str
tahun: int
buku = Buku("Laskar Pelangi", "Andrea Hirata", 2005)
print(buku)
print(buku.judul)Output yang Dihasilkan:
Buku(judul='Laskar Pelangi', penulis='Andrea Hirata', tahun=2005)
Laskar PelangiEnam baris deklarasi menggantikan tulisan tangan constructor dan __repr__ — dan nama field yang salah ketik langsung tertangkap saat object dibuat, bukan saat data dibaca. Anotasi str dan int pada tiap field juga menjadi dokumentasi hidup; pembahasan anotasi tipe menyusul pada Section Type Hints dan Static Analysis. Dataclass adalah anggota penting keluarga alat pemodelan data — lengkapnya di chapter Dataclasses pada Section Advanced Data Modeling.
Bahaya Over-Engineering #
Sisi buruk pemakaian class yang salah tidak berisik: program tetap berjalan, hanya saja membengkak. Contoh ekstremnya mudah dikenali:
class Penambah:
def tambah(self, a, b):
return a + b
kalkulator = Penambah()
print(kalkulator.tambah(2, 3))Output yang Dihasilkan:
5Class Penambah tidak menyimpan state, tidak menjaga aturan apa pun, dan hanya membungkus satu baris return a + b. Fungsi tambah(a, b) tiga baris menggantikannya dengan lebih sedikit konsep untuk diingat. Bentuk pembengkakan yang lebih halus lebih sering muncul di dunia nyata: class dengan satu method run(), hierarki BaseHandler setinggi tiga tingkat untuk satu implementasi, atau “Manager” yang hanya meneruskan panggilan ke tempat lain.
Tabel Keputusan #
| Gunakan OOP ketika | Utamakan fungsi/dictionary/dataclass ketika |
|---|---|
| Data punya invarian yang harus dijaga method | Data hanya mengalir lewat fungsi |
| Banyak class berbagi satu interface | Logika linier, satu arah, sekali jalan |
| State harus bertahan lintas pemanggilan | Perhitungan murni tanpa keadaan |
| Framework menuntut class (handler, model, test) | Skrip kecil, notebook, kode sekali pakai |
| Bentuk data perlu dideklarasikan, tanpa perilaku | — (gunakan @dataclass, bukan class manual) |
Sebagai penutup Section: dua arah lanjutan yang saling melengkapi sudah menunggu. Section Advanced Data Modeling memperdalam sisi data — chapter Properties untuk attribute terkendali, Dataclasses, hingga Special Methods dan Data Model yang membuat class kita terasa seperti class bawaan. Section Functional Programming memperkenalkan gaya sebaliknya — pure functions, immutability, dan komposisi fungsi — yang di tangan yang tepat justru paling bebas dari state. Programer Python yang matang berdiri nyaman di kedua dunia.