Ask HN: Codebase terbaik apa untuk mempelajari desain perangkat lunak?
(news.ycombinator.com)- Saya sedang berusaha meningkatkan kemampuan desain perangkat lunak, dan mendapat saran untuk mempelajari codebase yang sudah ada dan dirancang dengan baik
- Saya penasaran codebase apa saja yang dapat diakses publik yang dianggap sebagai gold standard dalam desain perangkat lunak
1. Rekomendasi codebase
- Proyek besar/perwakilan
- Git, Postgres, CPython
- "lieutenants model" dari Linux Kernel
- UNIX v6, BSDs
- Framework/library
- Spring Framework
- Laravel
- Library std Rust
- Codemirror 6
- Sistem/server
- Game/kasus khusus
- Materi pendidikan/pembelajaran
- xv6 (kelas OS MIT)
- pytudes (Peter Norvig)
- Lainnya
- Monocypher (library kriptografi)
- Implementasi bahasa Tcl
2. Membaca kode vs mempelajari dokumen/desain
- Keterbatasan hanya dari kode
- Codebase menunjukkan implementasi, tetapi menyembunyikan niat desain dan trade-off
- Pentingnya dokumen desain
- Catatan keputusan seperti ADR (Architectural Decision Records), RFC Rust, dan PEP Python jauh lebih bermanfaat untuk mempelajari desain
- Menulis dokumen desain itu sendiri juga bisa menjadi latihan
- Rekomendasi buku/literatur
- The Architecture of Open Source Applications
- Code Reading (Spinellis)
- Beautiful Code (O’Reilly, ISBN-10: 0596510047)
- Buku terkait Refactoring / Legacy Code
3. Teori pembelajaran yang berpusat pada praktik
- Pengalaman dan trial-and-error
- Desain dipelajari dengan berulang kali menghadapi masalah dan belajar cara menghindarinya
- Hanya membaca kode tidak cukup; pembelajaran terjadi saat menulis sendiri dan menyelesaikan kegagalan
- Pembelajaran berbasis minat
- Anda akan belajar lebih dalam jika membuat proyek yang benar-benar Anda minati
- Biaya kegagalan yang rendah
- Perangkat lunak memiliki biaya kegagalan lebih rendah daripada rekayasa fisik, sehingga belajar lewat mencoba dan gagal efektif
4. Perdebatan tentang sifat software engineering
- Pandangan rekayasa yang belum matang
- Jika lima engineer berkumpul lalu menghasilkan lima solusi berbeda, itu dianggap bukti ketidakmatangan sebagai disiplin rekayasa
- Pandangan sifat yang ramah eksperimen
- Perangkat lunak memiliki sedikit batasan sehingga banyak solusi bisa ada, dan tidak punya satu jawaban tetap seperti rekayasa fisik
- Batas antara seni dan rekayasa
- Desain juga merupakan tindakan artistik yang memiliki unsur estetika, tetapi dari sisi memenuhi kebutuhan fungsional tetap merupakan rekayasa
- Perangkat lunak berada di antara fleksibilitas artistik dan ketelitian engineering
5. Metode belajar alternatif
- Menganalisis kode yang buruk
- Bukan hanya kode yang dirancang baik, memperbaiki codebase yang buruk juga memberi efek belajar yang besar
- Belajar dari codebase sendiri
- Codebase internal tim sering disebut sebagai bahan yang paling banyak memberi pelajaran
- Namun, jika kode tim buruk, perlu dibarengi dengan contoh eksternal
- Pembelajaran yang disesuaikan dengan domain
- Membaca codebase yang mirip dengan masalah yang ingin Anda pecahkan adalah pendekatan paling efektif
Insight utama
- Codebase yang dirancang baik memang membantu, tetapi pembelajaran harus berjalan beriringan dengan memahami niat desain dan mengalami trial-and-error
- Dibanding hanya membaca kode, dokumen desain dan catatan keputusan adalah materi belajar yang paling penting
- Proyek-proyek berkualitas tinggi yang representatif (Git, Postgres, CPython, Rust std, dll.) punya nilai belajar tinggi
- Bukan hanya kode yang bagus, kode yang buruk dan kode milik sendiri justru sering lebih praktis untuk pembelajaran jangka panjang
Ringkasan komentar utama
Rekomendasi codebase yang representatif (CraigJPerry)
- Postfix mail server
- Dengan arsitektur yang berpusat pada keamanan, ia sudah menunjukkan struktur mirip microservices bahkan sebelum konsep itu populer
- Jika microservices modern menekankan distribusi pada organisasi besar, Postfix dirancang untuk keamanan dan kesederhanaan
- Spring Framework
- Mencerminkan budaya yang sangat mempertimbangkan kebutuhan developer Java di lingkungan enterprise
- Bisa dipelajari sebagai pendekatan desain yang berpusat pada pengguna
- Git
- Jika memahami konsep object database (blob, tree, commit) dan reference, sisanya adalah perluasan bertahap
- Perluasan yang konsisten dari konsep inti ditunjukkan sebagai contoh desain yang baik
- Varnish
- Sebagai reverse proxy berperforma tinggi, codebase-nya tersusun sangat baik hingga layak dipakai sebagai bahan belajar
- Linux Kernel Lieutenants Model
- Ini bukan codebase, tetapi layak dijadikan referensi sebagai model pengelolaan perangkat lunak berskala besar
- Bukan sekadar "kode yang dirancang baik", melainkan contoh-contoh di mana keputusan desainnya meninggalkan kesan yang kuat
Menekankan pembelajaran dari codebase kerja nyata (crystal_revenge)
- Nilai belajar terbesar bisa didapat dari codebase tim Anda sendiri
- Dalam proses hubungan yang rumit antara kebutuhan nyata dan implementasi, Anda akan mengalami pilihan baik dan buruk sekaligus
- Batasan paling besar di dunia nyata adalah tekanan waktu, dan inti pembelajaran adalah memahami keseimbangan antara desain ideal dan kenyataan
- Software yang baik adalah yang menyelesaikan kebutuhan pengguna, dan lewat pengalaman berulang Anda belajar merancang dengan peluang sukses lebih tinggi
Tautan ke diskusi dan materi sebelumnya (sprobertson)
- Topik yang sama sudah beberapa kali dibahas di HN
Kode vs dokumen desain (alphazard)
- Codebase hanyalah hasil implementasi, bukan desain itu sendiri
- Untuk mempelajari desain, menulis dokumen desain lebih efektif
- Dokumen harus cukup jelas sehingga orang lain bisa mengimplementasikannya secara langsung
- Jika alternatif dicantumkan beserta alasan penolakannya, itu menjadi bukti pertimbangan desain
- Desainer yang baik adalah orang yang mempertimbangkan ruang desain yang lebih luas lalu memilih titik yang tepat
Menekankan pemahaman sistem secara menyeluruh (RossBencina)
- Proses memahami keseluruhan codebase sangat bernilai
- Bukan hanya kode yang dirancang baik, tetapi juga latihan melihat gambaran besar sistem
- Memvisualisasikan relasi lewat diagram seperti UML sangat membantu
- Pendekatan belajar:
- Efektif membaca kode perangkat lunak yang mirip dengan yang sedang Anda kembangkan
- Disarankan memulai dari kode di domain yang sudah akrab (web framework, web server, library standar Python, VSCode, dll.)
- Pada awalnya lebih baik mendekati program kecil dan domain yang familiar
Tolok ukur desain yang baik (mamcx)
- Desain yang baik menunjukkan tujuan dan gagasan, sedangkan codebase menunjukkan sejauh mana itu diimplementasikan
- Desain yang baik bukan sekadar label seperti "cepat" atau "aman", melainkan harus mencakup pertimbangan konkret dan catatan trade-off
- Contoh: karakteristik seperti ini dapat diamati pada Erlang, Pascal awal, dan desain banyak RDBMS
- Library std Rust adalah bahan belajar yang baik karena menekankan keamanan dan konsistensi, dan kode serta dokumentasinya merefleksikan hal itu dengan baik
Keputusan desain yang tak terlihat (ben30)
- Saat melihat codebase yang dirancang baik, bagian terpenting justru adalah yang tidak terlihat
- Menghilangkan kompleksitas, menghindari abstraksi yang tidak perlu, dan menolak pola tertentu adalah keputusan berupa ketiadaan yang sangat penting
- Untuk melengkapinya, gunakan ADR (Architectural Decision Records)
- Mencatat alternatif, alasan menolaknya, dan dasar pemilihan agar konteks tetap tersimpan
- Sangat membantu baik bagi maintainer di masa depan maupun alat AI
- Saat belajar, efektif untuk melihat proyek yang bukan hanya punya kode, tetapi juga dokumen keputusan desain seperti ADR, RFC, PEP, dan sejenisnya
5 komentar
Saya beberapa kali mencoba membaca kodenya karena ada wawancara Evan You (pembuat Vue.js dan Vite) yang mengatakan TJ Holowaychuk, pembuat express.js, merancangnya dengan rapi dan indah. Meski saya belum bisa memahami gambaran besarnya, secara umum saya merasa kodenya tidak rumit, bersih, dan hanya berisi logika yang benar-benar diperlukan.
Komentarnya juga ditulis dengan baik, jadi meskipun ini kode dari 10 tahun lalu, cukup mudah untuk memahami inferensi tipe dan format DTO.
Menjadikan postingan blog tahun 2009 yang dipenuhi komentar spam sebagai referensi...
Opini Hacker News
Entah cuma saya atau bukan, tapi saya merasa cara paling efektif adalah benar-benar menabrak berbagai masalah berulang kali lalu belajar sendiri bagaimana menghindarinya. Lama-kelamaan kita jadi bisa mensimulasikan di kepala masalah apa yang mungkin muncul ke depan, dan pada akhirnya desain itu sendiri adalah penilaian untuk memprediksi serta menghindari berbagai masalah masa depan, menimbang trade-off seperti masalah mana yang ingin dihindari dengan tingkat usaha tertentu, dan apakah satu desain bisa menyelesaikan beberapa masalah sekaligus
Saya juga begitu. Pendekatan seperti "mengerjakan soal latihan" atau "mempelajari codebase" tidak terlalu cocok buat saya. Saya belajar secara alami saat membangun sesuatu yang benar-benar menarik bagi saya, sambil mengejar ketepatan dan ketelitian pada contoh yang saya buat. Tapi kadang saya masih merasa kemampuan saya belum cukup. Kalau saya bisa membaca kode selancar membaca buku dan langsung membayangkan perilakunya di kepala, saya rasa belajar itu sendiri akan jadi lebih menyenangkan
Mendengar bahwa orang belajar dengan menabrak masalah berkali-kali justru membuat saya merasa bidang software engineering ini masih belum matang. Bayangkan kalau jembatan atau rumah dibangun seperti itu, atau kalau ahli bedah dilatih dengan cara seperti itu—terdengar berbahaya hanya dengan membayangkannya. Seiring waktu, standar dan norma mungkin akan terbentuk, tapi untuk saat ini kondisinya benar-benar masih cair. Kumpulkan lima software engineer, beri mereka satu masalah, maka akan muncul lima solusi yang benar-benar berbeda, dan bukan cuma itu, mereka juga akan berdebat keras soal mana yang benar. Saya tidak merasa sikap "solusi yang bagus akan terlihat ketika kita melihatnya" itu cukup untuk disebut engineering yang layak
Saya juga selama ini belajar dengan cara ini secara konsisten, dan sepertinya akan terus begitu. Belajar dari production code sungguhan terasa seperti tantangan baru bagi saya. Saya tidak tahu seberapa berharganya, tapi setidaknya terdengar menyenangkan
Menurut saya ini mirip dengan belajar mengemudi dengan langsung naik mobil, menabrak, lalu merenung agar berikutnya tidak menabrak lagi. Padahal kenyataannya kita butuh keduanya. Dalam berkendara di jalan umum, kita jarang mencapai batas ekstrem sehingga sulit langsung diterapkan, tapi dalam balap, mengetahui persis batas seberapa jauh kita bisa mendorong kendaraan itu sangat penting. Tentu saya tidak berpikir profesi kita harus diperlakukan seperti kompetisi. Tapi kalau tidak membaca buku dan tidak belajar, waktu yang dibutuhkan akan sangat lama dan kecelakaan serta kerusakan tidak akan ada habisnya. Karena itu saya selalu bilang: baca, lalu baca lagi. Mungkin sekarang belum terasa perlu, tapi nanti saat pengalaman bertambah, pengetahuan itu pasti akan terpakai di suatu titik, dan Anda tidak akan panik seperti saat pertama kali belajar menurunkan gigi ke low gear sambil engine braking di turunan
Inilah inti persoalannya
Pikiran pertama saya saat mendengar pertanyaan ini adalah: "codebase tim Anda". Tidak ada cara yang lebih efektif untuk belajar desain perangkat lunak selain memahami secara mendalam mengapa solusi yang baik dan yang buruk diadopsi untuk masalah nyata. Pada dasarnya software adalah lapisan perantara kompleks yang menjembatani kebutuhan pengguna dan perilaku mesin. Kalau kekacauan ini tidak ada, semuanya mungkin sudah diautomasi dan software itu sendiri tidak lagi dibutuhkan. Software adalah bidang di mana mengejar ideal semata justru sering menghasilkan keputusan buruk. Dalam praktiknya, kita mengurangi trial and error dengan memahami "mengapa pilihan tertentu diambil di bawah tekanan tertentu". Pada saat yang sama, kita juga harus mempelajari metodologi praktis untuk bekerja cepat dan efektif. Tantangan terbesar di dunia nyata adalah batas waktu. Ini hampir tidak pernah dibahas dalam desain perangkat lunak teoretis, padahal dalam kenyataan kita selalu bekerja di bawah tekanan untuk mengirim kode dengan cepat. Sering kali tidak ada cukup waktu untuk melakukan sesuatu dengan cara yang kita inginkan atau dengan cara terbaik. Software yang baik adalah software yang menyelesaikan kebutuhan nyata pengguna. Ada solusi desain yang lebih sering menghasilkan eksekusi yang sukses, dan cara terbaik menemukannya adalah dengan menelaah secara mendalam kode yang benar-benar saya tulis
Bagaimana kalau penanya mencari saran dari luar karena merasa software timnya sendiri berantakan? Atau kalau yang bertanya hanya seorang mahasiswa?
Saya belum pernah memikirkan bahwa waktu yang dibutuhkan untuk implementasi juga bisa menjadi ukuran kualitas desain, tapi saya merasa itu sangat masuk akal. Saya juga belajar sangat banyak dari codebase tim saya. Sebagian besar datang dari mempelajari hal-hal baik pada desain yang bagus, dan pada bagian yang kurang bagus saya terus belajar sambil googling sendiri
Ini memang materi yang sudah beberapa tahun lalu, tapi ada seri "The Architecture of Open Source Applications" yang ditulis oleh banyak pemimpin proyek open source, dan bisa dibaca gratis secara online
https://aosabook.org/en/index.html
Pertanyaan ini sebenarnya sudah beberapa kali muncul, jadi saya kumpulkan beberapa tautan referensi
Source code Yanderedev
Saya tidak cukup memenuhi syarat untuk memberi jawaban yang benar, tapi sekitar 15 tahun lalu saya sangat menikmati membaca buku berjudul "Code Reading". Buku itu sangat cocok dengan topik ini
https://www.spinellis.gr/codereading/
Lihat daftar isi: https://www.spinellis.gr/codereading/toc.html
Saya rasa dulu ada juga buku lain dengan nama mirip, tapi saya tidak ingat persis
Pada praktiknya, codebase sering kali lebih banyak berisi implementasi daripada desain. Misalnya, walaupun sebuah sistem ditulis ulang total dalam bahasa lain, desainnya bisa saja tetap sama. Saya merekomendasikan latihan menulis dokumen desain. Jangan terlalu memikirkan bentuk dokumennya atau terikat pada template. Yang terpenting, orang lain harus bisa mengambil dokumen itu dan langsung mengimplementasikannya. Selain itu, dokumen tersebut bisa berfungsi sebagai "jejak pertimbangan". Cukup catat dengan jelas pendekatan apa yang dipilih, alternatif apa yang ada, dan mengapa alternatif itu tidak dipilih. Dengan mengakui dan membandingkan alternatif sejak awal, Anda memberi pembaca keyakinan bahwa keputusan itu sudah dipikirkan matang-matang. Yang dilakukan perancang sistem yang "baik" adalah melihat ruang desain yang lebih besar daripada orang lain, lalu menemukan titik-titik yang baik secara konsisten. Pilih satu masalah, jelajahi berbagai ruang desain, lalu dokumentasikan mana yang lebih baik dan mengapa
Saya rasa titik awalnya harus selalu pertanyaan: "Masalah apa yang ingin saya selesaikan?" Cari codebase yang menyelesaikan masalah itu, lalu analisis dengan fokus bagaimana hal tersebut diimplementasikan dalam praktik. Penting untuk diingat bahwa desain yang baik sangat terkait erat dengan konteks domain tertentu. Saya rasa Internal Model Principle milik Wonham juga berlaku pada kode. Misalnya, saya ingin menyelesaikan masalah unit testing untuk target embedded, jadi saya menganalisis proyek open source terkait dan meninjau secara kritis bagaimana tiap bagian kode ditulis serta alasannya. Saat membangun solusi saya sendiri, saya kembali merujuk ke kode-kode tersebut, dan semakin dalam pemahaman saya terhadap domain itu, semakin banyak juga yang saya pelajari
Dari pengalaman saya (30 tahun di software, 25 tahun praktik arsitektur, gelar master system architecture dari MIT), desain yang "baik" dalam arti abstrak sebenarnya tidak ada. Yang jelas ada adalah desain buruk—desain yang menghasilkan konsekuensi buruk—tetapi ukuran "baik" selalu bergantung pada konteks. Apa yang sedang dibangun, requirement seperti safety/security, dan yang terpenting tim yang benar-benar mengimplementasikannya beserta struktur timnya, semuanya sangat berpengaruh. Tim yang isinya hanya junior bisa saja salah memahami desain yang canggih lalu merusaknya. Seperti hukum Conway, struktur tim pengembang akan tercermin langsung pada software
Satu hal yang pasti saya sadari saat belajar software design adalah tidak ada jawaban universal. Andai ada, tentu akan menyenangkan, tapi memilih solusi terbaik di antara berbagai arsitektur dan paradigma kadang terasa membuat frustrasi. Meski begitu, begitu requirement dipahami dengan benar, pilihan biasanya akan jauh berkurang. Saat ini saya menangani sistem embedded yang sangat menuntut safety, dan lingkungan ini membuat saya sering mengambil keputusan yang dalam situasi lain mungkin sama sekali tidak akan saya gunakan
Pada akhirnya intinya adalah menghindari kompromi yang benar-benar konyol, dan juga menghindari pilihan-pilihan terburuk jika dilihat dari sudut pandang yang lebih luas. Yang selalu saya rasakan di lapangan adalah bahwa ini bukan pertarungan untuk menemukan arsitektur terbaik, melainkan perjuangan berkelanjutan untuk "menghindari keputusan yang secara fundamental buruk"
Dulu saya pernah membuat daftar rekomendasi yang sangat sederhana, dan menurut saya itu masih relevan
https://medium.com/@012parth/what-source-code-is-worth-studying-8755f88f8de5
Ada jebakan di tengah..
Apakah ini source code Yanderedev... wkwk