4 poin oleh GN⁺ 2023-12-09 | 1 komentar | Bagikan ke WhatsApp
  • Melalui pengalaman menulis ulang kode resize editor grafis dengan fokus menghapus duplikasi lalu akhirnya mengembalikannya, tulisan ini menunjukkan bahwa obsesi pada clean code bisa justru merusak kemudahan melakukan perubahan nyata
  • Implementasi lama mengulang rumus untuk tiap handle pada Rectangle, Oval, Header, dan TextBlock, sedangkan implementasi baru berusaha menghapus duplikasi dengan memisahkan arah dan bentuk lalu menggabungkannya
  • Tepat setelah refactoring, ukuran kode berkurang setengah dan titik perubahan terkumpul di satu tempat, tetapi ketika kemudian dibutuhkan perilaku khusus per bentuk dan per handle, abstraksi justru bisa menjadi penghambat
  • Masalah yang lebih besar daripada penilaian teknis adalah langsung check-in ke master tanpa berdiskusi dengan rekan yang menulis kode aslinya, yang bisa merusak pembangunan kepercayaan dalam tim
  • “Kebersihan” bukan tujuan, melainkan hanya alat untuk menangani sistem yang kompleks, dan yang lebih penting daripada bentuk kode adalah apakah tim dapat bersama-sama merespons perubahan

Pengulangan dalam kode resize editor grafis

  • Pada kanvas editor grafis, ada kode untuk me-resize bentuk seperti persegi panjang dan oval menggunakan handle kecil di tepinya
  • Implementasinya berjalan, tetapi rumus untuk menghitung posisi dan ukuran berulang untuk setiap bentuk dan arah handle
    • Rectangle memiliki metode seperti resizeTopLeft, resizeTopRight, resizeBottomLeft, resizeBottomRight
    • Oval memiliki metode seperti resizeLeft, resizeRight, resizeTop, resizeBottom
    • Header dan TextBlock juga masing-masing memiliki metode resize
  • Jika pengguna menekan Shift, proses resize juga harus menangani menjaga rasio, sehingga rumusnya menjadi semakin banyak

Abstraksi untuk menghapus duplikasi

  • Pengulangan terlihat pada dua sumbu
    • Terjadi pengulangan di antara handle dengan arah yang sama: Oval.resizeLeft() dan Header.resizeLeft() sama-sama menangani aksi drag handle kiri
    • Terjadi pengulangan di antara metode dalam bentuk yang sama: beberapa metode pada Oval semuanya menangani oval
  • Struktur baru mencoba membagi kode menjadi Directions dan Shapes untuk menggabungkan perilaku per arah dan perilaku per bentuk
    • Directions berisi top, left, bottom, right
    • Shapes berisi Oval, Rectangle
    • createHandle, createBox digunakan untuk menggabungkan handle dan bentuk
  • Dalam pendekatan ini, dibuat konfigurasi handle seperti fourCorners, fourSides, twoSides, lalu itu digunakan untuk membentuk Rectangle, Oval, Header, TextBlock

Ilusi tepat setelah refactoring

  • Setelah refactoring, ukuran total kode berkurang setengah dan duplikasi tampak seolah hilang
  • Saat ingin mengubah perilaku arah atau bentuk tertentu, terasa cukup mengubah satu tempat alih-alih banyak metode
  • Larut malam ia melakukan check-in perubahan ke master, sambil merasa telah merapikan kode berantakan milik rekannya dengan elegan

Masalah yang terungkap keesokan harinya

  • Keesokan harinya atasan meminta perubahan itu dibatalkan, dan saat itu sulit menerimanya karena ia yakin kode baru lebih bersih daripada kode lama
  • Setelah waktu berlalu, keputusan itu ternyata benar karena dua alasan
    • Ia menulis ulang dan melakukan check-in kode tanpa berbicara dengan orang yang menulis kode aslinya
    • Demi mengurangi duplikasi, ia justru mengorbankan kemudahan menghadapi perubahan kebutuhan
  • Tim engineering yang sehat harus terus membangun kepercayaan, dan penulisan ulang besar-besaran atas kode rekan kerja bisa menjadi pukulan besar bagi kolaborasi

Biaya abstraksi yang salah

  • Setelah itu, muncul banyak kasus khusus dan perilaku khusus untuk berbagai handle pada berbagai bentuk
  • Untuk mengakomodasi kebutuhan seperti itu dalam struktur abstraksi baru, kode bisa menjadi beberapa kali lebih rumit
  • Sebaliknya, struktur asli yang “berantakan” justru cukup mudah diberi perubahan seperti ini karena tiap metode terpisah
  • Menghapus duplikasi kode tidaklah gratis; saat mendapatkan satu kemampuan, kita bisa kehilangan kemampuan lain

Memikirkan kembali “kebersihan”

  • Banyak developer bisa mengalami masa terobsesi pada “clean code” dan penghapusan duplikasi
  • Saat tidak percaya diri pada kode yang ditulis sendiri, mudah untuk menggantungkan kebanggaan pada hal-hal yang bisa diukur seperti aturan lint yang ketat, aturan penamaan, struktur file, atau tidak adanya duplikasi
  • Ketika sudah bisa membuat abstraksi, kita bisa mulai percaya bahwa abstraksi adalah kebajikan dan ingin menerapkannya setiap kali melihat kode berulang
  • Kita perlu memikirkan secara mendalam hasil engineering nyata apa yang benar-benar terkait dengan rasa “bersih” atau “kotor” itu
  • Bukan hanya bagaimana kode terlihat, tetapi juga bagaimana kode itu berubah dan diperbaiki bersama orang-orang dalam tim yang penting

Saat harus melepaskan clean code

  • Clean code bukan tujuan, melainkan upaya untuk memahami sistem yang kompleks
  • Saat kita belum yakin dampak perubahan dalam codebase akan seperti apa, clean code bisa menjadi mekanisme pertahanan yang membantu memberi arah
  • Pada awalnya, pengalaman menyederhanakan kode kompleks lewat ekstraksi fungsi atau refactoring kelas bisa terasa menyenangkan
  • Namun kita tidak boleh berhenti di sana lalu menjadi “fanatik clean code”
  • Biarkan clean code menjadi penunjuk arah, tetapi pada titik tertentu kita harus melepaskannya

1 komentar

 
GN⁺ 2023-12-09
Pendapat Hacker News
  • Duplikasi kode kadang tidak apa-apa, tetapi itu bukan bukti bahwa Clean Code itu buruk
    Rasanya refaktorisasi yang dilakukan agak berlebihan; kalau hanya mengekstrak “10 baris matematika yang berulang” menjadi sebuah fungsi, hasilnya mungkin akan lebih rapi
    Rekan tim yang tidak menjadikan 10 baris itu sebagai fungsi juga tidak sepenuhnya benar, jadi kalau saya mungkin akan menolak PR-nya, tetapi saya tidak akan menulis ulang sendiri
    Menulis ulang PR orang lain adalah penghinaan cepat yang menutup ruang diskusi, dan sering kali kita juga tidak tahu konteks mengapa kode itu ditulis seperti itu
    Jika tidak ada standar coding, PR harus ditinjau dan ditolak; kalau dibiarkan di-commit dengan alasan “Clean Code tidak penting”, dalam beberapa bulan codebase itu akan menjadi tempat yang tidak ingin dikerjakan siapa pun
    Yang bisa dipelajari di sini bukan Clean Code, melainkan komunikasi dan tenggang rasa

    • Menulis ulang langsung kode orang lain yang sudah berfungsi bukan hanya menghina penulisnya, tetapi juga tindakan tidak profesional karena membuang waktu untuk mengubah kode yang punya maintainer tersendiri
      Penulis aslinya juga kehilangan kesempatan untuk belajar bagaimana kode berkualitas rendah benar-benar membuang waktu
      Sekalipun pendekatan Clean Code lebih baik, inti masalah di sini bukan kodenya, melainkan ia membuang waktunya sendiri tanpa memberi umpan balik yang berguna
      Yang terbaik adalah membuat penulis asli menaikkan standarnya, sementara dirinya mengerjakan hal lain yang memang perlu disentuh. Dengan kata lain, jawaban yang benar adalah code review
    • Pelajarannya lebih dekat ke “jangan menerapkan aturan secara berlebihan tanpa mempertimbangkan kompromi sesuai konteks”, dan itu pelajaran yang butuh waktu untuk dipahami
    • Setelah melihat lebih dari 20 tahun, gagasan bahwa “karena 10 baris berulang tidak diekstrak menjadi fungsi, maka kodenya buruk” umumnya sering dimiliki orang-orang yang berfokus pada hal yang keliru di codebase
      Orang-orang seperti ini sering kali menyelesaikan sesuatu yang bukan masalah, alih-alih menyelesaikan masalah nyata, sekaligus menciptakan masalah masa depan
      Pada implementasi pertama, memang lebih tepat untuk tidak mengabstraksikan potongan kode sangat kecil seperti 10 baris itu. Kode yang melakukan tepat hal tersebut mudah diperbaiki nanti, dan mengabstraksikan 10 baris demi manfaat yang belum terbukti tidak banyak artinya
      Clean Code sama sekali tidak penting, begitu pula sebagian besar aturan atau “prinsip” serupa. Justru hal-hal semacam itulah yang dipegang orang-orang untuk membenarkan struktur seperti sarang lebah yang mereka tumpuk di codebase seiring waktu
      Akibatnya, kode cenderung menjadi terlalu diabstraksikan, sulit diubah, lambat, dan sulit dipahami
      Jika membutuhkan prinsip, cukup lihat apakah hal yang sebenarnya dilakukan program, yaitu transformasi data, diekspresikan dengan jelas dan mudah diubah
      Sebagian besar prinsip SOLID tidak membantu melihat apa itu transformasi data dan bagaimana terjadinya, atau malah menghalanginya, sehingga umumnya kurang berguna untuk memahami program nyata
    • Menurut saya, cara tulisan aslinya mengungkapkan hal ini kurang baik
      Jika melihat refaktorisasi yang diusulkan, 10 baris itu sebenarnya tidak identik, hanya mirip
      Rumus untuk mengubah ukuran sudut kiri atas persegi panjang dan rumus untuk mengubah kanan bawah elips itu berbeda. Dari luar tampak mirip, tetapi di beberapa tempat ada - alih-alih +
      Dalam kasus ini, kompleksitasnya ada pada geometri itu sendiri, dan “mengabstraksikannya” hanya memindahkan kekusutan ke tempat lain, bukan menghilangkannya secara mendasar
      Mungkin saja ada abstraksi matematis cerdas seperti sistem bilangan khusus, tetapi jika tidak bawaan bahasa, biaya mengimplementasikan operasi khusus dengan bilangan bulat dasar kemungkinan lebih besar daripada manfaatnya
  • “Clean Code” perlu rebranding
    Selama lebih dari 25 tahun berkarier, saya terus melihat penolakan tanpa henti terhadap design pattern, abstraksi, penghapusan duplikasi, dan sebagainya
    Alasannya selalu sama: abstraksi membuat kode lebih rumit, tidak ada waktu untuk menulis Clean Code, semuanya hanya selera dan opini
    Namun tujuan Clean Code adalah membuat kode lebih sederhana dan lebih mudah dipelihara ketika kebutuhan berubah
    Nilai perangkat lunak terletak pada kemampuannya untuk berubah seiring waktu. Kalau tidak, kita bisa saja memakai rangkaian tetap yang implementasi dan pemeliharaannya jauh lebih mudah dan murah
    Jika refaktorisasi tidak mencapai tujuan ini, dan atasan bisa meyakinkan bahwa perubahan kebutuhan di masa depan justru menjadi lebih sulit dipelihara, maka kode itu memang tidak “clean”
    Tidak berdiskusi dengan penulis asli adalah masalah prosedur dan etiket di luar ranah Clean Code. Bersikap kasar dan sepihak tidak menghapus nilai Clean Code

    • Menurut saya penolakan itu ditujukan pada resep yang terlalu absolut
      Buku terkenal Clean Code menyebut “tanpa duplikasi” sebagai syarat sistem yang dirancang dengan baik, dan menyebut duplikasi sebagai musuh utama pekerjaan tambahan, risiko tambahan, dan kompleksitas yang tidak perlu
      Dengan definisi ini, penghapusan duplikasi menjadi sinonim dari penyederhanaan, dan itu salah
      Menghapus duplikasi adalah memperkenalkan dependensi. Jika dependensi itu memodelkan masalah dengan baik, ia bisa menjadi abstraksi yang baik sekaligus penyederhanaan; jika tidak, ia hanya kompresi yang menyamar sebagai abstraksi
      Sebagai catatan, kutipan ini adalah penyebutan Simple Design dari Kent Beck yang muncul di Clean Code
    • “Clean Code” dipakai dengan dua makna
      Yang satu adalah perasaan subjektif bahwa suatu kode bagus, dan yang lain adalah mengikuti buku Clean Code serta pedoman terkaitnya
      Semakin banyak orang merasa bahwa keduanya cukup berbeda. Mengikuti sebagian pedoman buku itu kadang justru menghasilkan kode yang sama sekali tidak bersih
      Di dunia ideal, semua orang ingin menulis clean code, tetapi makin sedikit orang yang merasa Clean Code adalah cara yang baik untuk mencapai tujuan itu
      Terutama abstraksi berlebihan dan penghapusan duplikasi kini dianggap banyak orang sebagai sumber kode yang berantakan
    • Yang saya pelajari di industri adalah, kode yang ditulis serapi apa pun tidak akan bertahan lama ketika bertemu kebutuhan produk
      Terkadang technical debt sudah tertanam dalam kebutuhan produk itu sendiri, sehingga tidak bisa diperbaiki dengan refaktorisasi atau praktik terbaik; yang bisa dilakukan hanya mengurangi rasa sakitnya
    • Terdengar seperti logika “bukan orang Skotlandia sejati”
      Tujuan Clean Code dan hasil praktiknya sangat berbeda. Sebab orang-orang umumnya tidak bisa memprediksi kondisi masa depan kode, bahkan ketika kebutuhan sudah ada di depan mata
      Clean Code memancing pertanyaan mengerikan “bagaimana jika?”, dan ini mudah menjadi kotak Pandora yang menunda rilis tanpa akhir
      Hampir selalu lebih baik menulis kode sesuai hal yang diketahui, dan membiarkan orang yang punya pengalaman domain memimpin arsitektur
    • Jika menyebut daftar alternatif, sebagian besar abstraksi yang kita buat itu buruk, bahkan yang kita anggap baik pun biasanya demikian
      Banyak abstraksi yang baik sudah ada di library. Tentu saja, sayangnya tidak selalu begitu
      Abstraksi buruk memakan waktu, dan kode juga merupakan cara berkomunikasi dengan orang lain di tim, jadi bagaimana anggota tim menerima komunikasi itu jauh lebih penting daripada cara berpikir saya sendiri
  • Seorang rekan menulis banyak kode dengan copy-paste, lalu Anda melakukan refactoring setelah commit
    Rekan itu mengeluh kepada atasan, atasan memarahi Anda, dan Anda akhirnya menyimpulkan bahwa lain kali Anda akan membiarkan kekacauan tetap ada di codebase
    Ada pelajaran yang bisa diambil di sini, tetapi itu bukan berarti copy-paste lebih baik daripada menulis fungsi
    Refactoring seharusnya diajukan sebagai perubahan terpisah dengan menandai penulis aslinya untuk direview
    Namun fakta bahwa rekan itu tidak berbicara langsung dan malah membawanya ke atasan, lalu atasan menyuruh mengembalikannya, adalah sinyal yang cukup buruk

    • Kalau saya, saya akan mengirim pesan pribadi Slack ke rekan itu: “Di tiap fungsi ini ada 10 baris matematika yang berulang; bukankah lebih baik dipisahkan ke fungsi tersendiri?”
      Jawaban yang mungkin adalah “Tidak, alasannya…” atau, lebih jarang, “Benar juga, besok saya kerjakan”
      Tanpa keributan, semua orang terhindar dari masalah, dan mungkin ada yang belajar sesuatu
    • Jika itu copy-paste malas, memakai fungsi untuk bagian yang berulang—yakni melakukan abstraksi—lebih baik dari sudut pandang DRY
      Namun penulis menambahkan konteks penting. Ia menukar kemungkinan perubahan kebutuhan dengan pengurangan duplikasi, dan kemudian setiap handle untuk bentuk membutuhkan banyak kasus khusus dan perilaku tersendiri
      Ini menunjukkan perbedaan antara DRY insidental dan DRY esensial
      Library A dan B sering terlihat konsisten satu sama lain sehingga kodenya menjadi sama, tetapi sebenarnya itu bisa saja kebetulan
      Jika wrapper untuk lib A dan wrapper untuk lib B berisi kode yang sama tetapi membungkus hal yang benar-benar berbeda, mengabstraksikannya akan berakhir buruk
      Hal yang sama berlaku untuk “15”. Jika “semua daftar harus selalu menampilkan 15 item”, maka mengabstraksikan angka 15 itu benar; tetapi jika itu masing-masing adalah “15 lagu teratas di homepage” dan “default 15 komentar di bawah lagu”, mengikat kedua angka 15 itu justru pilihan yang lebih buruk
    • Sinyal bahaya terbesar adalah mengubah kontribusi rekan tanpa komunikasi apa pun
      Sinyal bahaya kedua adalah refactoring itu sendiri juga bukan refactoring yang bagus. Modularitasnya kurang, masih saling terikat, dan hanya sedikit mengurangi duplikasi
    • Menandai penulis asli pun bisa menimbulkan masalah
      Itu bisa terdengar seperti, “Kode yang kamu tulis kurang bagus, jadi saya tulis ulang. Ada keberatan?”
      Solusi terbaik mungkin adalah meminta penjelasan dalam bentuk “review terlambat”, mengusulkan solusi, dan berharap penulis asli tidak sekadar mengabaikannya
    • Di akhir tulisan ada bagian penting: dalam perubahan codebase berikutnya, handle per bentuk harus diperlakukan secara khusus, dan itu sulit pada struktur hasil refactoring tetapi mudah pada kode yang berulang
      Intinya adalah menyadari bahwa kode akan berubah di masa depan. Kebutuhan berubah, dan kode terkait juga berubah
      Jika kita membuat abstraksi yang membatasi kemampuan perubahan itu, kita merusak kemampuan diri kita di masa depan untuk menyesuaikan codebase
      Terutama abstraksi yang sudah menghabiskan banyak waktu dan usaha sering membuat kita terikat secara emosional, sehingga kita membuang lebih banyak waktu untuk memaksakan perubahan agar cocok dengan solusi yang elegan
      KISS memang tepat
  • Kasus ini terlihat seperti masalah “tidak ada yang suka orang sok pintar”
    Ini sering terjadi terutama ketika developer junior belum belajar bahwa pekerjaan bukan hanya antara dirinya dan komputer, melainkan antara dirinya, komputer, dan orang lain
    Versi yang lebih rapi kemungkinan besar akan diterima jika ia benar-benar berbicara dengan penulis asli dan menyepakati cara yang lebih baik
    Judul tulisan ini tampaknya lebih cocok menjadi belajar cara bekerja dalam tim daripada “Selamat tinggal, Clean Code”

    • Ungkapan “tidak ada yang suka orang sok pintar” menangkap lingkungan pengembangan dengan baik
      Kode yang lebih kompleks mungkin diterima sebagai ancaman, dan dianggap sebagai pesaing yang perlu ditekan lewat rantai manajemen
      Jika Anda junior, Anda perlu tahu bahwa pernyataan ini bergantung pada konteks. Di banyak tempat kerja, kesederhanaan lebih penting daripada fleksibilitas, fitur bahasa yang membingungkan dihindari, dan cara kerja yang menghabiskan banyak waktu di depan keyboard serta bahasa semacam itu lebih disukai
      Sebaliknya, filosofi yang menekankan pembelajaran seumur hidup, software craftsmanship, dan refleksi proses bertabrakan sepenuhnya dengan lingkungan seperti ini
      Upaya untuk menjadi lebih baik tidak populer di kalangan orang yang tidak bertumbuh
      Keduanya pilihan hidup yang valid. Software bisa menjadi tempat nyaman untuk bekerja 7 jam lalu pulang, sekaligus dunia eksplorasi yang hanya dibatasi imajinasi dan kecerdasan
      Jika Anda ingin menemukan hal baru, berhati-hatilah menghabiskan puluhan tahun bersama orang-orang yang takut pada hal yang belum dikenal
      Singkatnya, jika insentif Anda tidak selaras dengan rekan-rekan, pertimbangkan untuk pergi
    • Menurut saya judulnya baik-baik saja
      Tulisan ini punya alasan untuk dicintai lama, dan telah membuka mata banyak developer yang jatuh ke perangkap yang sama
      Bahkan saat bekerja sendiri, Anda bisa merancang abstraksi yang rapi secara berlebihan lalu kelak tersandung oleh abstraksi itu sendiri
    • Masalah seperti ini biasanya lebih sering dilakukan oleh senior yang mabuk kuasa daripada junior
  • Masalahnya adalah perubahan langsung di-commit ke branch main tanpa review
    Setiap perubahan kode perlu review rekan, entah melalui pair programming atau PR tradisional, agar eskalasi seperti ini bisa dicegah
    Atasan itu atasan yang buruk. Alih-alih memarahi, ia seharusnya menyadari bahwa proses yang baik sedang hilang
    Jika tim memiliki budaya code review, ketika karyawan baru yang terlalu bersemangat mencoba hal seperti ini, rekan akan berkata “terima kasih, tapi bukan begini” atau “ide bagus, coba lakukan seperti ini”
    Secara terpisah, saya pikir kode tidak boleh direfactor tanpa alasan yang baik. Kode buruk pun bisa saja merupakan kode yang hampir tidak pernah perlu diubah
    Waktu terbaik untuk melakukan refactoring adalah ketika Anda perlu mengubah perilaku dan menyadari bahwa struktur yang ada membuatnya terlalu sulit
    Sayangnya, dalam kasus ini tampaknya pelajaran yang dipetik keliru

    • Code review setelah merge juga sepenuhnya baik-baik saja, dan dalam beberapa hal malah lebih baik
  • Entah kenapa semua orang hanya membahas apa yang seharusnya ia lakukan sebagai gantinya. Ini pelajaran yang sepenuhnya sah
    Di dunia keuangan, kita terus berurusan dengan produk yang sampai taraf tertentu mirip tetapi tidak sepenuhnya sama. Opsi saham dan opsi valas sama-sama opsi dan punya harga pelaksanaan, serta dihargai dengan suatu versi Black-Scholes, tetapi dalam praktiknya sangat berbeda
    Orang yang baru bergabung sering sangat tergoda untuk menggeneralisasi banyak perilaku, dan kami sering berada di posisi atasan dalam tulisan asli: menyuruh developer muda untuk tenang dan membiarkannya tetap terpisah
    Ini bukan berarti mengucapkan selamat tinggal pada clean code, melainkan bahwa kita harus menghindari abstraksi berlebihan agar benar-benar bisa mempertahankan clean code

    • Contoh keuangan itu tepat, tetapi di sini yang dibahas adalah geometri
      Yang dilakukan handle umum adalah transformasi afin, yaitu translasi, rotasi, penskalaan, dan refleksi; jika penskalaannya seragam, itu transformasi similaritas. Ini dijamin bekerja pada bentuk apa pun
      Masalah sebenarnya adalah jangan mengabstraksikan sesuatu yang belum cukup kita pahami. Terutama jika kita tidak tahu kemungkinan apa yang akan muncul di masa depan
      Misalnya, jika kita mengira oval hanya mencakup lingkaran dan elips, kita akan cukup terkejut saat oval “sungguhan” pertama muncul
    • Saya paham inti tulisannya, tetapi judulnya memang mudah dibaca sebagai alasan untuk membenarkan kode yang berantakan
      Karena penulis tidak secara aktif membedakan kode berantakan dan kode “tidak clean”, orang lain jadi mencoba membuat pembedaan itu
    • Cukup kentara bahwa semua orang di sini merasa lebih tahu daripada anggota tim saat itu dan penulisnya, padahal tidak punya konteks selain beberapa baris pseudocode
      DRY itu bernilai, tetapi abstraksi punya biaya. Selalu ada trade-off
  • Salah satu alasan saya menyukai bahasa seperti Haskell adalah karena maksimalisme abstraksi berada di level bahasa, bukan di level coding
    Semua orang sepakat tentang apa yang seharusnya dilakukan Applicative. Tantangannya bergeser lebih ke kanan dalam pipeline dari ide ke kode, yaitu menemukan Applicative yang cocok untuk masalahnya
    Sebagian besar pola desain berorientasi objek punya padanan yang alami dan terdefinisi dengan baik di lingkungan seperti ini, dan membantu mengurangi abstraksi yang spesifik per proyek
    Bagi pemula, biaya awal untuk mempelajari bahasanya besar, dan sering terjadi ketika membuka kode Haskell lain, ada sekitar 12 ekstensi compiler yang belum pernah dilihat sebelumnya dan harus dipahami
    Meski begitu, ekstensi compiler itu bisa dibawa ke semua proyek setelahnya, jadi saya menganggapnya keuntungan bersih
    Bagi ahli, kekurangannya adalah perlu gelar PhD untuk bisa memperkirakan berapa banyak RAM yang akan dimakan cats

    • Alasan kita tahu apa yang dilakukan Applicative dan Monad adalah karena ada hukum matematis
      Jika suatu kode memakai Applicative atau Monad, kita bisa mengetahui perilakunya berkat hukum-hukum itu
      Pola desain berorientasi objek tidak punya hukum seperti itu. Itu konsep atau pola yang didefinisikan longgar sehingga terbuka untuk interpretasi dan kustomisasi pribadi, tetapi tidak punya hukum konkret yang memberi tahu persis apa itu dan perilaku atau output apa yang harus diharapkan
    • Sebagai pengguna Haskell, saya setuju bahwa kemampuan abstraksi bahasanya sangat bagus
      Namun untuk contoh di tulisan blog itu, saya harus mengatakan bahwa mengikuti jalur clean code sering sekali berakhir menyusahkan diri sendiri di masa depan
      Jika nanti kita harus mempelajari abstraksi itu lagi untuk memahaminya, abstraksi tersebut tidak bermanfaat
    • Tulisan asli akan lebih baik jika timnya lebih banyak memakai prinsip berorientasi objek, kecuali jika tim tersebut secara umum menolaknya. Kalau tim seperti itu, saya mungkin akan bekerja di tempat lain
      Tempat yang paling alami cocok untuk OOP adalah widget GUI dan implementasi editor
      Aturan yang menyatukan aturan-aturan OOP lainnya adalah jangan bertanya, perintahkan
      Dalam contoh ini, handle akan dibagikan dengan cara yang diketahui, dan tiap bentuk akan memiliki titik kontrolnya sendiri. Jika handle kotak berubah, kita bisa memanggil updateControlPoints(changedHandle), dan jika titik kontrol berubah, kita bisa memanggil updateBoxHandles(changedControlPoint)
      Pemisahan lain yang rapi juga mungkin, tetapi saya akan melakukannya seperti itu
    • Kita mungkin bisa sepakat tentang apa yang seharusnya dilakukan Applicative
      Namun soal library parsing mana yang dipakai, memilih Data.Text.Strict atau Data.Text.Lazy, seberapa banyak memakai gaya point-free, memilih . dan >>> atau kombinator lain, serta ekstensi bahasa apa yang digunakan, kesepakatan sulit dicapai
      Saya suka Haskell, tetapi ia mengalami masalah yang mirip dengan bahasa lain. Orang-orang benar-benar tidak bisa sepakat tentang cara terbaik untuk mengerjakan sesuatu
    • Selangkah lebih jauh, pakai saja Rust dengan tipe afin
      Kita bisa mendapatkan sistem tipe Haskell dan performa yang dapat diprediksi
  • Bagian matematika yang berulang cukup dipindahkan ke fungsi terpisah, lalu dipanggil dari fungsi pengubahan ukuran
    Fungsi pengubahan ukuran itu sendiri tampak berulang karena membentuk interface, jadi refactoring yang menghilangkannya adalah keliru
    Namun matematika yang dilakukan fungsi-fungsi itu adalah target yang sepenuhnya valid untuk merapikan kode

    • Benar. Itu tampak seperti arah yang jelas, dan biasanya saya juga begitu
      Hasilnya memang banyak fungsi kecil yang murni, tetapi itu tidak menjadi masalah karena mudah diuji dan di-refactor
    • Terutama jika ini refactoring, saat bekerja dengan tim biasanya lebih baik menanganinya secara bertahap
      Ada banyak cara dan pola untuk memecahkan masalah yang sama, tetapi membongkar interface yang sudah dipakai orang lain bukan awal yang baik
      Keunggulan abstraksi adalah kita bisa mengubah bagian dalam agar lebih fleksibel tanpa merusak bagian lain
      Langkah pertama yang baik adalah, seperti yang dikatakan, membuat fungsi matematika yang lebih fleksibel di lapisan bawah dan membiarkan sisanya tetap seperti semula
      Setelah itu, kita bisa berdiskusi lebih dalam dengan tim tentang cara berkomunikasi agar interface menyediakan facade yang jelas sementara implementasinya diabstraksikan
  • Yang digambarkan di sini terasa seperti abstraksi yang buruk
    Masalah sebenarnya adalah orang-orang merancang hanya dengan melihat dua atau tiga contoh, tanpa memastikan apakah rancangan itu cukup umum untuk mengakomodasi penggunaan di masa depan

    • Pendekatan yang sangat baik khususnya adalah mengabstraksikan bagian-bagian yang sama hanya menjadi fungsi-fungsi yang sangat sederhana
      Abstraksi harus dilakukan dari bawah ke atas, bukan dari atas ke bawah
      Tidak perlu membuat satu titik tunggal tempat semua hal terjadi dan yang menangani kombinasi 2^n
      Meski begitu, kita tetap bisa mengurangi pengulangan, mengubahnya di satu titik, dan mempertahankan kemampuan untuk melakukan perubahan khusus saat diperlukan
    • Masalah di dunia nyata adalah tidak ada orang yang, saat menulisnya, tahu bahwa dirinya sedang memakai abstraksi yang buruk. Kalau tahu, mereka tidak akan memakainya
      Jadi sekadar mengatakan “hindari abstraksi yang buruk” atau “buat agar bisa mengakomodasi penggunaan di masa depan” tidaklah cukup
      Pada umumnya, tidak ada orang yang bisa memprediksi masa depan
      Abstraksi harus digunakan dengan sangat hati-hati bahkan ketika terasa benar. Lebih baik menjadi skeptis ekstrem
    • Masalah pada versi “clean” adalah semuanya sepenuhnya saling terikat
      Jika menyentuh satu hal di kode matematika, semuanya ikut terpengaruh
      Pada suatu titik, lebih mudah membiarkan sebagian kode duplikat tetap ada, menandai kemiripannya dengan petunjuk struktur kode atau komentar, dan seiring waktu menekankan perbedaan utamanya lewat komentar
      Pendekatan clean code untuk jenis kode seperti ini tidak menangani kebutuhan yang berubah dengan baik
      Pada akhirnya, ini mudah berubah menjadi sekumpulan fungsi helper dengan beberapa jalur kode tergantung lokasi pemanggilan
      Kadang ini bisa diabstraksikan, dan sebagian orang mungkin sudah menyadarinya, tetapi kalimat sebelumnya sebenarnya menjelaskan polimorfisme berorientasi objek
      Namun bagaimana mungkin kita mengetahui kebutuhan yang tepat sejak awal? Mencoba “clean code” pada tahap sedini ini hanya akan berakhir sebagai abstraksi buruk atau overengineering
      Pendekatan yang benar adalah tidak melakukan apa-apa, mencatat kemungkinan masalah, lalu menunggu sampai kita tahu lebih banyak tentang domain masalahnya
    • Saya makin menyukai cara menemukan pola melalui perubahan. Mencari pola dari fitur baru dan perbaikan bug
      Kode yang agak duplikatif tetapi mudah dipahami seperti contoh awal tidak terlalu saya khawatirkan
      Namun jika harus memperbaiki isu yang sama di tiga tempat, atau menambahkan kode fitur baru di tiga tempat, barulah saya khawatir
      Saat itu saya mulai memikirkan apakah kode yang harus diubah atau ditambahkan bisa didorong ke suatu lokasi bersama dengan cara tertentu
    • Benar sekali
      Orang membaca design pattern atau DRY, lalu karena masih belajar, umumnya menerapkannya dengan keliru, kemudian menyalahkan teks aslinya
  • Rob Pike pernah mengatakan bahwa salah satu alasan Go menjadi seperti itu adalah “salinan kecil lebih baik daripada dependensi kecil”
    Semakin lama saya memprogram, semakin saya memahami maksudnya
    Pengulangan itu sendiri bukan masalah. Yang penting adalah memahami unit yang sedang dibaca dan mungkin akan diubah
    DRY sering kali berarti menambahkan abstraksi lain, dan jika abstraksi itu tidak cukup ortogonal, sekarang kita harus mempertimbangkan dua unit, bukan satu, sehingga situasinya justru menjadi lebih buruk