2 poin oleh GN⁺ 2023-10-31 | 1 komentar | Bagikan ke WhatsApp
  • Pelajaran terbesar yang terus berulang dari pengalaman panjang dalam pengembangan adalah bahwa kompleksitas adalah “musuh abadi” codebase, dan membuat perubahan kecil dapat merusak bagian lain yang tidak terduga
  • Alat paling kuat untuk mengurangi kompleksitas adalah mengatakan “no” pada fitur dan abstraksi, tetapi saat kompromi realistis dibutuhkan, gunakan solusi 80/20 untuk menyampaikan sebagian besar nilai dengan sedikit kode
  • Desain dan pengujian lebih menekankan pencarian batas yang baik setelah bentuk sistem mulai terlihat, daripada abstraksi yang terlalu dini; integration test yang bertahan lama lebih diutamakan daripada unit test
  • Tool, type system, logging, debugger, dan desain API harus mengurangi beban kognitif developer, dan nilai praktis besar dari type system ada pada autocomplete IDE
  • Teknik bernama baik seperti DRY, separation of concerns, microservices, SPA, generics, dan refactoring berlebihan juga bisa menjadi jalur masuk kompleksitas jika membuat kode lebih sulit dipahami dan dipelihara

Kompleksitas adalah risiko utama codebase

  • Kompleksitas membuat sistem yang awalnya bisa dipahami tiba-tiba sulit ditangani, dan perubahan di satu tempat merusak bagian lain yang tampaknya tidak terkait
  • Kompleksitas bisa masuk melalui developer atau project manager yang berniat baik, dan kadang kompleksitas yang kita masukkan sendiri menjadi sumber masalah
  • Tidak ada “klub” serbaguna untuk mengatasi kompleksitas; respons terbaik adalah tidak memasukkannya sejak awal

“no” dan “ok”: penolakan dan kompromi realistis

  • Senjata terbaik untuk mencegah kompleksitas adalah “no
    • “Fitur itu tidak dibuat”
    • “Abstraksi itu tidak dibuat”
  • Namun meski “no” adalah nasihat engineering yang baik, itu bisa merugikan untuk kompensasi lebih besar atau promosi
  • Saat secara realistis harus berkompromi, jawab “ok” lalu cari solusi 80/20
    • Cara mengimplementasikan 80% nilai yang diinginkan dengan 20% kode
    • Mungkin tidak memiliki semua fitur hiasan dan terlihat sedikit kurang rapi, tetapi menyampaikan sebagian besar nilai sambil menjaga kompleksitas tetap rendah
  • Karena project manager kadang melupakan detail requirement, pindah, atau keluar dari perusahaan, pendekatan 80/20 kadang menjadi pilihan yang lebih baik

Desain dan pemecahan kode berbahaya jika terlalu dini

  • Di awal proyek, bentuk sistem masih belum jelas seperti “air”, jadi hindari pemecahan yang terlalu dini
  • Seiring waktu, batas yang baik akan terlihat
    • Interface dengan bagian sistem lainnya sempit
    • Kompleksitas internal disembunyikan dengan sedikit fungsi atau abstraksi
  • Jika abstraksi dibuat terlalu awal, abstraksi yang salah mudah muncul, sehingga lebih baik memberi bobot pada menunggu
  • Untuk developer yang ingin membuat abstraksi besar di awal, memberikan artefak sekali pakai seperti UML, atau meminta demo yang berjalan besok, bisa membantu
  • Prototipe awal menunjukkan kode yang benar-benar berjalan dan batasan realistis dengan lebih cepat

Testing bukan “ditumpuk belakangan”, melainkan “berjalan bersama saat bentuknya terbentuk”

  • Testing mencegah banyak masalah, tetapi menolak cara yang memaksakan test first bahkan sebelum domain dipahami
  • Lebih disukai menulis sebagian besar test setelah prototipe, ketika kode mulai mengeras
  • Sikap melewati test sambil berkata “di mesin saya jalan” sangat buruk
  • Preferensi per jenis test cukup jelas
    • unit tests: berguna di awal proyek, tetapi mudah rusak saat implementasi berubah dan dapat menyulitkan refactoring
    • end to end: menunjukkan perilaku seluruh sistem, tetapi saat rusak penyebabnya sulit dipahami dan jika sering rusak mudah diabaikan
    • integration tests: cukup tinggi untuk melihat kebenaran sistem, cukup rendah untuk menemukan penyebab dengan debugger, sehingga mendekati titik terbaik
  • Setelah API pada batas stabil, investasikan kuat pada integration test di sekitarnya
  • Pertahankan end-to-end test sebagai kumpulan kecil yang terkelola baik, berfokus pada fitur UI paling umum dan beberapa edge case penting
  • mocking digunakan hanya saat benar-benar perlu, dan jika memungkinkan hanya pada unit batas yang besar
  • Jika bug ditemukan, sebagai pengecualian lebih disukai mereproduksinya dulu dengan regression test, lalu memperbaikinya

Agile, refactoring, Chesterton's Fence

  • Agile sendiri bukan yang terburuk dan bisa digunakan sebagai salah satu cara mengorganisasi tim development, tetapi “agile shaman” yang menggunakannya seperti alat pembebasan dari kegagalan perlu diwaspadai
  • Prototipe, tool yang baik, dan perekrutan developer yang baik lebih penting bagi keberhasilan software; proses apa pun bukan silver bullet yang menyelesaikan semua masalah
  • Refactoring berguna terutama ketika kode sudah mengeras di tahap akhir proyek, tetapi semakin besar refactoring, semakin besar kemungkinan gagal
    • Lakukan dalam bagian-bagian kecil
    • Pertahankan sistem sebisa mungkin tetap berjalan
    • Setelah tiap tahap selesai, baru lanjut ke tahap berikutnya
  • Abstraksi berlebihan dapat berujung pada kegagalan refactoring dan kegagalan sistem
    • J2EE adalah contoh yang merugikan banyak proyek
    • OSGi mencoba mengurung kompleksitas tetapi malah membuatnya lebih kuat, dan membutuhkan beberapa man-year pengerjaan ulang
  • Chesterton's Fence terkait dengan sikap untuk tidak menghapus kode yang tampak buruk sebelum memahami mengapa ia ada
  • Kode yang sedang berjalan harus dihormati meski tidak sempurna, dan semakin besar sistemnya, semakin perlu waktu untuk memahaminya lebih dulu

Microservices dan tool

  • Microservices menambahkan network call ke masalah sulit berupa membagi sistem dengan benar
  • Tool sangat meningkatkan produktivitas dan pemahaman developer
    • Di lingkungan baru, sebaiknya luangkan waktu untuk mempelajari tool
    • Jika mempelajari tool selama 2 minggu, kecepatan development bisa menjadi 2 kali lebih cepat
    • Jika tidak ada dokumentasi, perlu bertanya ke developer lain dan menggali lebih dalam
  • Code completion di IDE membuat developer tidak perlu mengingat semua API, dan hampir menjadi keharusan dalam development Java
  • Debugger yang baik sangat penting
    • Conditional breakpoint
    • Evaluasi ekspresi
    • Penelusuran stack
  • Developer baru harus mempelajari debugger yang tersedia secara mendalam, dan itu bisa mengajarkan lebih banyak tentang komputer dibanding kelas universitas

Type system, ekspresi, DRY

  • Nilai terbesar type system ada pada dukungan tooling yang menampilkan daftar operasi yang mungkin saat mengetik titik
  • Type correctness juga baik, tetapi code completion dan navigasi memiliki nilai praktis yang lebih besar
  • Developer yang menggunakan type system secara terlalu abstrak perlu diwaspadai
    • Generics bisa sangat berbahaya
    • Dalam sebagian besar kasus, lebih disukai membatasinya sekitar container class saja
  • Daripada menjejalkan conditional expression pendek dalam satu baris, lebih baik memecahnya ke variabel perantara dengan nama bermakna untuk memudahkan debugging dan pemahaman
  • DRY adalah nasihat yang baik, tetapi perlu keseimbangan
    • Kode duplikat yang sederhana dan jelas kadang lebih baik daripada callback, closure, atau object model yang kompleks
    • Jika penghapusan duplikasi itu sendiri meningkatkan kompleksitas, hasilnya bisa merugikan

Separation of concerns, closure, logging

  • Separation of Concern adalah ide yang kuat, tetapi dalam praktiknya bisa membuat orang membuang waktu karena harus bolak-balik di banyak file untuk memahami perilaku
  • Sebagai alternatif, lebih disukai locality of behavior
    • Jika kode diletakkan dekat dengan “hal yang berperilaku”, saat melihat objek itu kita langsung tahu apa yang dilakukannya
  • Closure cocok untuk mengabstraksikan operasi collection, tetapi seperti garam, sedikit saja sudah cukup
  • “callback hell” di JavaScript adalah contoh kompleksitas akibat penggunaan closure yang berlebihan
  • Logging sangat penting, terutama di lingkungan deployment cloud
    • Tinggalkan log di setiap percabangan logika utama
    • Untuk request yang melewati beberapa mesin, sertakan request ID agar log bisa dikelompokkan
    • Jika memungkinkan, atur level log secara dinamis
    • Jika memungkinkan, atur level log per pengguna untuk men-debug masalah pengguna tertentu
  • Library logging bisa kompleks, tetapi investasi untuk membangun infrastruktur logging dengan benar akan memberi imbalan besar kemudian

Concurrency, optimisasi, API

  • Concurrency adalah area yang pantas ditakuti, dan sebisa mungkin model yang sederhana lebih disukai
    • Stateless web request handler
    • Remote work queue yang tidak saling bergantung
    • API sederhana
  • Di web, optimistic concurrency bisa cocok
  • Struktur data concurrency seperti ConcurrentHashMap di Java juga harus digunakan dengan hati-hati
  • Optimisasi harus dimulai setelah masalah konkret teridentifikasi melalui profil performa nyata
    • Jangan hanya melihat CPU
    • Akses jaringan setara dengan banyak siklus CPU, jadi kurangi jika memungkinkan
    • Jika langsung berusaha menghapus O(n^2) begitu melihat nested loop, kompleksitas bisa meningkat
  • API yang baik harus membuat developer tidak perlu banyak berpikir
    • Jika penulis API terjebak dalam sudut pandang implementasi atau domain, API menjadi sulit digunakan
    • Untuk kasus sederhana, sediakan API sederhana; untuk kasus kompleks, sediakan API yang lebih kompleks secara terpisah—pelapisan seperti ini baik
    • Jika object-oriented, perilaku sebisa mungkin harus berada pada objek terkait
  • Contoh stream/collector di Java dikritik sebagai API yang membuat pekerjaan umum harus memutar secara tidak perlu

Parsing, Visitor Pattern, frontend

  • Parser dengan pendekatan recursive descent dianggap menyenangkan dan indah
  • Parser generator membuat kode yang dihasilkan sulit dipahami dan di-debug, serta menyembunyikan sifat rekursif grammar
  • Parser produksi nyata kebanyakan menggunakan recursive descent, dan Bob Nystrom dengan Crafting Interpreters direkomendasikan
  • Visitor pattern diringkas singkat sebagai “bad”
  • Memisahkan frontend dan backend lalu menghubungkan library SPA dan GraphQL JSON API lewat HTTP nyaris seperti membuat dua sarang kompleksitas
  • Waspadai arus yang memakai library frontend besar bahkan untuk website sederhana atau pekerjaan memasukkan form ke database
  • Untuk menurunkan kompleksitas, dibuat htmx dan hyperscript
    • Mempertahankan HTML sederhana
    • Menghindari banyak JavaScript
  • React lebih baik untuk pekerjaan dan beberapa tipe aplikasi, tetapi dipandang sebagai pilihan yang memasuki jalan kompleksitas frontend

Tren, FOLD, impostor syndrome

  • Development punya banyak tren, terutama lebih menonjol di frontend
  • Pendekatan baru yang disebut revolusioner harus disikapi dengan skeptis
    • Di bidang komputer, banyak ide sudah pernah dicoba setidaknya sekali
    • Ide buruk bisa kembali dengan nama baru
  • Baik jika developer senior berkata secara terbuka, “ini terlalu kompleks sehingga sulit dipahami”
  • FOLD adalah singkatan dari Fear Of Looking Dumb, yaitu kondisi tidak bisa mengakui kompleksitas karena takut terlihat bodoh
    • Jika senior mengatakan sesuatu itu kompleks, junior juga lebih mudah mengakui bahwa mereka tidak memahaminya
    • FOLD adalah sumber utama yang memberi kekuatan pada kompleksitas, terutama bagi developer muda
  • Developer bolak-balik antara perasaan menguasai segalanya dan perasaan tidak tahu apa-apa; impostor syndrome itu umum
  • Jika semua orang merasa seperti impostor, maka tidak ada yang benar-benar impostor, dan developer muda bisa terus menjalani karier meski ada frustrasi dan kekhawatiran

Bacaan yang direkomendasikan dan kesimpulan

1 komentar

 
GN⁺ 2023-10-31
Opini Hacker News
  • Aneh melihat orang-orang pintar tertarik pada kompleksitas seperti ngengat ke api
    Butuh bertahun-tahun untuk belajar melawan dorongan melakukan overengineering
    Sekali mulai terlihat, hal itu jadi sulit diabaikan, dan sekarang saya bisa langsung tahu apakah kode mengalami overengineering
    Sayangnya, sekitar 99% kode tampak seperti hasil overengineering, dan ada insentif kuat bagi pengembang untuk memaksimalkan ketidak-tergantian diri mereka dan jam tagihan
    Bahkan pengembang yang tampak sepenuhnya mekanis dan tanpa ego pun sering melakukan overengineering, dan ini bekerja secara tidak sadar
    Banyak pengembang tidak memikirkan secara sadar setiap baris kode yang mereka tulis; mereka hanya menetapkan tujuan lalu mengeluarkan kode pertama yang sedikit mendekatkan ke tujuan itu, sehingga mereka tidak menyadari bahwa di setiap langkah sebenarnya ada alternatif yang lebih baik

    • Dalam pengalaman saya, insentif untuk meningkatkan ketidak-tergantian pengembang dan jam tagihan hampir tidak pernah menjadi penyebab overengineering
    • Saya terus bergulat dengan masalah ini
      Pertama, saya suka teka-teki yang menarik. Kode komersial khususnya sering kali cukup membosankan jika dibuat dengan benar, jadi tanpa sadar saya mendorong fitur yang menyenangkan untuk diimplementasikan. Dan yang dimaksud menyenangkan di sini pada akhirnya adalah fitur yang membuat semuanya jauh lebih rumit dari perlu
      Kedua, saat sedang memprogram sesuatu, semua pilihan yang saya buat tampak wajar dan perlu. Baru setelah saya menjauh dari kode itu dan mencoba memahaminya lagi dengan sudut pandang baru, saya bisa melihat betapa kacaunya hasil yang saya buat
      Untuk kebanyakan masalah, solusi yang paling menonjol sering kali cukup rumit, dan untuk tahu di mana mencari solusi yang sederhana dibutuhkan kebijaksanaan, keterampilan, dan pengetahuan domain. Solusi yang sederhana dan bersih hampir tidak pernah terasa jelas
      “Kita pelan-pelan sedang membuat message queue setengah jadi. Pakai saja message queue standar”, “Kita sedang membuat protokol framing biner kustom yang penuh bug. Pakai saja protobuf/msgpack”, “Jangan bikin protokol RPC kustom untuk mengambil data, pakai REST di atas HTTP saja. Dengan begitu kita bisa menaruh nginx di tengah untuk cache respons backend dan membuang cache kustom”
    • Ini mengingatkan saya pada kalimat seperti “saya tidak punya waktu untuk menulis surat pendek, jadi surat ini menjadi panjang” dari sebuah surat penulis
      Pada akhirnya, kalau ada waktu dan ada penghargaan untuk itu, kita bisa menulis kode yang sempurna, sederhana, dan tanpa pengulangan. Tapi kebanyakan orang justru dihargai karena berhasil merilis sesuatu, dan karena menunjukkan kapabilitas teknis lewat jumlah kerja, kecerdasan, dan kemampuan desain yang masuk ke rilis itu
      Kesimpulan alaminya adalah semuanya membengkak menjadi gumpalan solusi sementara yang berlebihan dan mengalami overengineering, lalu ditulis ulang setiap 3–7 tahun
      Saya belum melihat datanya, tetapi “waktu paruh penulisan ulang” tampaknya mungkin berkorelasi dengan tingkat turnover atau masa kerja rata-rata. Bahkan jika orang berusaha lebih keras untuk tidak melakukan overengineering, kemungkinan besar toh akan ditulis ulang juga
      Sebagai seorang perfeksionis ini sangat mengganggu, tetapi kadang membuat sesuatu yang rumit dan overengineered lebih dihargai daripada meluangkan waktu lebih lama memikirkan solusi sederhana terbaik. Mungkin ada organisasi yang lebih baik, tetapi setelah 9 tahun bekerja sebagai software engineer saya belum menemukannya
      Proyek open source adalah contoh tandingan terbaik yang terpikir oleh saya, tetapi library yang bagus pun sering ditulis ulang atau diberi versi baru ketika maintainernya berganti. Ada perbedaan insentif finansial yang sangat besar antara open source dan sampah perusahaan yang dilihat banyak software engineer profesional penuh waktu di HN. Ini mirip membandingkan makalah akademik yang dipoles rapi dengan email kerja yang ditulis seadanya
    • Dalam kasus saya, overengineering biasanya datang dari arah sebaliknya. Dari terlalu banyak berpikir saat menulis kode, dan dari punya praduga tentang seperti apa codebase itu seharusnya
      Kalau tidak salah saya ingat Casey dari Handmade Hero menyebut gaya pemrogramannya sebagai “compression-based”. Tulis dulu kodenya, lalu pisahkan secara bertahap hal-hal yang memang seharusnya bersama
      Saya melakukan abstraksi saat ada pengulangan, bukan membuat abstraksi lewat desain yang disengaja. Saya makin sering memakai pendekatan ini
    • Jika kesimpulan “99% kode tampak mengalami overengineering” menghasilkan jawaban seperti 99%, apakah tidak mungkin bahwa meskipun pelajaran yang Anda dapatkan selama ini valid, ada masalah pada model berpikir yang Anda bangun?
      Itu sendiri tidak otomatis berarti salah, tetapi jika ini dipakai untuk menilai kualitas pekerjaan orang lain, tampaknya besar kemungkinan ada bias kuat di dalamnya
  • Saya sangat suka situs ini dan selalu tertawa karenanya. Bagian favorit saya terutama adalah microservices
    “grug bertanya-tanya mengapa big brain mengambil masalah yang sudah paling sulit, yaitu membagi sistem dengan benar, lalu menambahkan network call juga di dalamnya. Bagi grug ini terlihat sangat membingungkan”

    • Saya suka situs ini jadi sering membacanya. Orang-orang yang saya kenal mungkin sudah bosan melihat grug brain sebagai semacam manifesto pengembangan perangkat lunak
      “kompleksitas sangat, sangat buruk”
      “jika harus memilih antara kompleksitas dan duel satu lawan satu melawan tyrannosaurus, grug memilih tyrannosaurus. Setidaknya grug bisa melihat tyrannosaurus”
  • Saya agak punya keberatan pada bagian tentang tipe
    grug bilang bahwa lebih dari 90% nilai sistem tipe ada pada daftar yang muncul secara ajaib saat menekan titik di keyboard, tetapi para junior di perusahaan kami sering mendorong kode ke produksi yang rusak karena akses null, lalu Sentry yang memberi tahu hal itu
    Selama periode fokus pengembangan, biasanya ada sekitar satu bug akses null yang terdeteksi per junior developer per hari
    Jika memakai sistem tipe yang benar dengan pemeriksaan statis, IDE bisa memberi tahu, “ini bisa jadi null, kamu yakin?” dan itu sepertinya akan sangat membantu
    Dan bahkan tanpa tipe statis pun, pelengkapan otomatis tetap memungkinkan
    Bagian yang berbunyi, “para dukun sistem tipe otak besar bilang akurasi tipe adalah inti sistem tipe, tetapi grug melihat para dukun itu tidak sering merilis kode. Kode yang tidak dirilis mungkin dalam arti tertentu benar, tetapi itu bukan kebenaran yang dimaksud grug” terasa kasar dan tidak perlu
    Saya terutama telah merilis kode dalam C, PHP, Python, Haskell, dan Python bertipe, dan pada bahasa bertipe tingkat bug yang lolos sampai produksi jauh lebih rendah. Itu salah satu alasan saya menyukai tipe
    Selain itu, refactoring jadi jauh lebih mudah. Saat mengubah sesuatu yang dipakai luas, kita bisa memeriksa semua call site yang rusak di seluruh codebase secara andal dalam hitungan detik, dan itu sangat membantu untuk terus memperbaiki codebase yang makin besar

    • Apa itu salah? Dari pengalaman yang dia sampaikan sendiri pun, sepertinya dia bahkan tidak menerima sistem tipe yang memaksa pembuktian formal
      Sebaliknya, dia tampaknya menerima sistem tipe kompromistis yang menangkap sebagian masalah dan, yang terpenting, memberi keajaiban auto-complete, tanpa tersandung semua detail yang dibutuhkan untuk pembuktian akurasi penuh
    • Itu cuma bercanda. Mungkin saya justru termasuk pihak yang jadi sasaran olok-olok, tetapi menurut saya tidak perlu ditanggapi terlalu sensitif
      Tampaknya dia menganggap tipe statis setingkat C atau Java itu oke atau bagus, dan hal-hal yang lebih mewah seperti yang terlihat di Rust atau Scala adalah pemborosan waktu. Saya pikir dia sepenuhnya salah, tetapi begitulah hidup
    • Bukankah tulisan aslinya justru pro bahasa bertipe? Pada akhirnya rasanya posisinya sama, jadi saya bingung
    • “Dukun” yang dimaksud di sini tampaknya bukan orang seperti Anda
      Saya memahaminya sebagai “dukun sistem tipe otak besar” yang belum tentu orang yang menulis kode, melainkan misalnya orang yang menjual kursus tentang topik itu dan membuat orang bersemangat
      Di bagian awal tulisan, dia juga memakai istilah “dukun” saat membahas Agile, dan memang cukup banyak orang yang pekerjaannya lebih dekat ke menjual kursus daripada pengembangan perangkat lunak sungguhan
    • Saya pernah bekerja dengan “dukun sistem tipe otak besar” seperti itu. Malah tulisan ini terasa seperti analisis yang sangat ramah dan murah hati
      Sulit bertahan bekerja dengan orang-orang yang terobsesi pada hirarki tipe, dan pembenarannya biasanya berkutat di dunia “bagaimana jika” dan “tetapi itu tidak sound”
      Banyak penurunan kualitas yang dipicu sistem tipe berasal dari orang-orang yang percaya bahwa jika memasukkan cukup banyak tipe, bug bisa dicegah sepenuhnya, padahal itu tidak benar
  • Dalam beberapa bulan ke depan, sepertinya semua orang akan naik kereta HTMX, dan itu akan mengguncang pikiran banyak developer muda, menghemat banyak energi dunia, dan membuat banyak orang bahagia
    Lalu ketika orang-orang muda yang penasaran itu terus mengklik tautan di htmx.org dan menemukan hyperscript, rasanya akan seperti momen para vampir keluar di Dusk till Dawn

    • Semua orang naik kereta HTMX adalah loop tak berujung dalam JavaScript
      Seseorang yang lelah dengan kompleksitas JavaScript membuat library JavaScript sederhana, orang-orang berbondong-bondong karena kesederhanaannya, library itu lalu menjadi rumit karena harus mendukung semua fitur web, dan kemudian seseorang yang lelah dengan kerumitan itu membuat library JavaScript sederhana lagi
      Saya mulai dengan JavaScript murni dan bertarung melawan IE5/6 selama beberapa tahun, lalu jQuery menyelamatkan semua orang, saya melewati AngularJS karena kurang suka, dan saat React beta keluar saya menyukainya karena idealisme functional programming. Sekarang saya sedang menerobos tumpukan transpiling, hot reload, Typescript, dan library React berat
      Saya juga sudah membuat beberapa proyek dengan Intercooler dan HTMX. HTMX secara keseluruhan solid, tetapi ini bukan kereta pertama yang lewat di kota ini
    • Ah, jadi Carson Gross adalah penulis grug brained developer dan htmx
      Saya ingin melihat kritik yang benar-benar nyata terhadap htmx
      Secara pribadi saya merasa tantangan besar yang terus ada di web adalah mencari cara memperbarui halaman dengan baik, dan kita terus mencoba segala macam pendekatan. Dari situ muncul kelelahan, dan beberapa gagasan menjadi ekstrem atau berubah jadi rongsokan seiring waktu
      Htmx tampak seperti reaksi tandingan ala grug yang menuntut lebih sedikit, dengan keras memegang YAGNI
      Masa depan tidak pasti, tetapi pekerjaan seperti signals masih tampak seperti sesuatu yang suci. Banyak percobaan dilakukan dari berbagai arah, dan kita masih merintis garis depan ini maupun yang lain
      MobX dan Svelte juga sudah melalui perjalanan panjang. Perjalanannya belum selesai, dan terus bergulat dengan monster bernama kompleksitas menurut saya bukan tanda kelemahan, walaupun pemikiran konservatif atau ala grug mungkin melihatnya begitu; saya ingin menganggapnya sebagai upaya yang pantas untuk mencapai bukan sekadar yang sederhana, melainkan sederhana dan bagus
    • Saya tertawa saat membaca kalimat itu lalu benar-benar memeriksanya
      _="on load wait 5s then transition opacity to 0 then remove me"
      Oh, jangan
      _="on htmx:error(errorInfo) fetch /errors {method:'POST', body:{errorInfo:errorInfo} as JSON} "
      Oh, jangan!
  • Saya sudah bekerja sebagai developer selama 30 tahun, dan saya mengakui bahwa di masa awal saya arogan dan mengira saya lebih pintar daripada orang lain. Saat itu saya berada di kubu “otak besar” yang menyukai semua iblis kompleksitas
    Sepuluh tahun kemudian saya menjadi lebih dekat ke developer “Grug brain”, dan sekarang saya fokus pada solusi paling sederhana yang tetap bisa bekerja, meskipun saya tahu itu mungkin tidak sempurna. Itu tetap oke karena membawa kita lebih dekat ke hal yang benar dan memungkinkan perbaikan berulang
    Hal terbaik yang bisa dilakukan sebagai developer adalah menghapus kode. Sekarang ada requirement yang kami pertahankan selama 2 tahun dan tiba-tiba itu bukan requirement lagi, dan saya benar-benar bersemangat memikirkan banyak kode yang bisa dicabut. Karena semuanya jadi lebih sederhana

    • Saat menghapus kode, ada sensasi menyenangkan yang sulit dijelaskan di bagian belakang kepala
      Rasanya seperti bisa merasakan ruang yang terbebaskan secara fisik
  • Grug juga muncul di komentar untuk tulisan Philosophy of Software Design seminggu lalu, dan menurutku diskusinya waktu itu cukup bagus. https://news.ycombinator.com/item?id=38011938
    “Aku juga merasakan hal yang persis sama soal grug. Aku tidak melihat orang benar-benar sepakat tentang apa yang sederhana, jadi saat seseorang bersikap seolah ‘kesederhanaan’ versi mereka adalah sesuatu yang begitu jelas sampai manusia gua pun pasti setuju, itu terasa seperti gaya sok”
    Kesederhanaan sering kali adalah salah satu hal yang paling rumit untuk ditemukan. Aku sering melihat orang yang yakin bahwa segala sesuatu di sekitar mereka itu rumit dan harus dibengkokkan menjadi sederhana, kecuali hal yang mereka sendiri kerjakan. Rasanya seperti sikap lemah yang berbahaya dan bergantung pada otoritas

    • Poin yang bagus. Tapi menurutku inti masalahnya tetap bahwa filosofi yang buruk mendorong kompleksitas
      filosofi grug brain adalah memilih kesederhanaan dengan harga berapa pun, kecuali jika benar-benar tidak bisa dihindari
      filosofi big brain menurut pandangan grug adalah memilih reusability dengan harga berapa pun, kecuali jika benar-benar tidak bisa dihindari
      Masalah dari filosofi ini adalah ia mengunci pilihan desain generasi pertama dan membuat perbaikan iteratif jadi lebih sulit
      Memang benar kesederhanaan sulit ditemukan, tetapi kunci untuk menemukannya adalah perbaikan iteratif
    • Hal yang sangat bagus dari tulisan Grug adalah betapa penuhnya tulisan itu dengan nuansa dan kerendahan hati. Ini bukan gaya sok
    • Menurutku yang perlu diukur adalah jumlah baris kode
      minimum lokal bergerak tergantung pada kompleksitas dari apa yang sedang dibangun, jadi ada ruang bagi beberapa pandangan yang cukup cerdas untuk sama-sama benar pada saat yang sama
      Ini bukan metrik yang sempurna, tapi arahnya benar, dan dalam skala log metrik ini bekerja sangat baik
  • Senang akhirnya tahu nama konsep Pagar Chesterton, karena aku sudah tak terhitung kali memakai dan menjelaskannya
    Ini sangat sering terjadi saat bekerja dengan pengembang junior. Ketika mereka melihat “sampah legacy usang”, reaksi pertama mereka adalah ingin membongkarnya atau membuang semuanya lalu membangun ulang dari nol
    Dalam beberapa kasus, membiarkan mereka mencobanya sendiri juga bisa jadi pelajaran, tetapi baik untuk diingat bahwa orang-orang yang datang sebelum kita tidak semuanya benar-benar idiot, dan biasanya ada alasan kenapa mereka melakukannya seperti itu
    Kadang memang itu kode tua berantakan yang benar-benar perlu diganti, tetapi bahkan dalam kasus seperti itu pun sering kali ada catatan yang didapat dengan susah payah tentang semua sudut dan kasus batas yang perlu dipahami dan ditangani untuk membangun sesuatu di domain tersebut

  • Bagian tentang testing benar-benar bagus. Sangat sesuai dengan apa yang sudah kupelajari selama beberapa tahun
    Untuk menemukan bug, integration test adalah titik yang tepat
    Mock object cenderung membuat segalanya jadi terlalu rumit, dan walaupun aku masih kadang memakainya, aku menghindari penggunaannya secara sistematis
    Unit test terlalu rapuh di hadapan refactoring, sedangkan integration test justru membantu refactoring

    • Trik yang kusukai adalah menyiapkan integration test yang mengikuti skenario demo, lalu menjalankannya tepat sebelum demo. Kalau bisa, jalankan dua kali
    • Sangat tidak setuju. Integration test bekerja dengan sangat baik sampai mencapai tingkat skala atau kompleksitas tertentu, tetapi setelah melewati batas itu hasilnya jadi sangat buruk
      Unit test memang lebih sulit ditulis dan dipelihara, tetapi saat gagal, test ini jauh lebih mudah dipahami dan di-debug, sehingga dalam jangka panjang jauh lebih tahan
      Test yang paling buruk adalah integration test yang diam-diam bergantung pada fakta bahwa integration test lain sudah dijalankan lebih dulu. 99% waktu tetap benar, lalu hancur saat ada perubahan yang mengubah urutannya
    • Kesimpulanku soal testing adalah begini
      Jika sebuah tim punya kode yang sederhana, maka testing sangat membantu. Tetapi kalau tim itu tidak punya kode sederhana, yang biasanya memang begitu, lebih baik menghabiskan waktu untuk menyederhanakan kode daripada menulis test
    • Menurutku banyak hal bergantung pada apa yang dianggap sebagai “unit”
      Jika satu leaf function dijadikan unit, itu sering kali terlalu rendah levelnya, tetapi modul yang lebih besar dengan antarmuka yang relatif stabil bisa menjadi unit yang baik dan produktif untuk diuji
  • “Kompleksitas itu sangat sangat buruk”
    “Senjata terbaik melawan iblis jiwa kompleksitas adalah kata sihir ‘tidak’”
    “Sedih tapi benar: nasihat karier yang ideal adalah, setelah belajar mengatakan ‘ya’ lalu gagal, belajar menyalahkan grug lain”
    itulah kebijaksanaan kompleks dari grug

  • Ini juga pernah didiskusikan saat itu
    The Grug Brained Developer - https://news.ycombinator.com/item?id=31840331 - Juni 2022, 374 komentar

    • kompleksitas tetap sangat buruk