- Usulan desain sistem yang dimulai dengan “let’s just” biasanya menjadi jauh lebih kompleks daripada perkiraan, dan penilaian arsitektur yang baik sangat bergantung pada aturan praktis serta pemahaman konteks
- Struktur plugin, penambahan API, dan lapisan abstraksi memang terlihat masuk akal, tetapi dalam praktiknya harus sekaligus menanggung kompatibilitas perilaku, pemeliharaan, keamanan, performa, dan tuntutan ekosistem
- Pemrosesan asinkron, kontrol akses, dan sinkronisasi data tampak seperti topik yang familier, tetapi dalam lingkungan produk mudah berujung pada bug yang sulit direproduksi, perancangan ulang model keamanan, dan masalah sinkronisasi
- Cross-platform dan native escape bisa valid untuk produk awal yang sederhana, tetapi ketika fitur platform dan state internal mulai menyimpang, akan sulit menjaga kualitas dan konsistensi
- Pola-pola ini tidak selalu salah, tetapi kebanyakan tidak diperlukan atau ada alternatifnya; alih-alih memilih pendekatan yang mudah gagal, masalah perlu dipecahkan kembali dari prinsip pertama (first principles)
Mengapa “let’s just” berbahaya
- Usulan yang datang setelah “let’s just” dalam 9 dari 10 kasus akan menjadi pekerjaan yang jauh lebih rumit daripada yang dibayangkan di ruang rapat
- Rekayasa juga punya sifat ilmu sosial, sehingga apa yang berhasil sangat bergantung pada konteks
- Ketika seseorang mengatakan suatu pendekatan tidak akan berhasil, para engineer sering menerimanya sebagai tantangan untuk segera membuktikan sebaliknya
- Sebagian besar manajemen engineering dan arsitektur perangkat lunak adalah gabungan aturan praktis (rule of thumb) dari pengalaman dan pelajaran yang didapat dengan susah payah
“Mari buat saja agar bisa dipasang plugin”
- Ketika satu implementasi terasa tidak cukup, menambahkan implementasi baru ke arsitektur yang sama membuatnya tampak seolah pemanggil API bisa mendapat peningkatan atau fitur baru tanpa perlu diubah
- Namun karena “API bukanlah file header atau dokumentasi, melainkan perilakunya sendiri”, hampir tidak ada plugin yang benar-benar sekadar bisa langsung bekerja
- Dalam perangkat lunak modern, komponen yang paling mendekati plugin adalah driver perangkat
- Driver di masa lalu memiliki kualitas perilaku yang buruk sehingga tidak lagi bisa ditoleransi, atau OS modern bergerak ke arah membangun driver mereka sendiri
- Untuk benar-benar membuat struktur yang bisa dipasangi plugin, Anda harus merancang implementasi kedua bersamaan dengan implementasi dasar, agar setidaknya ada bukti bahwa pendekatan itu pernah berhasil sekali
“Mari tambahkan saja API”
- Setelah produk atau perusahaan mencapai tingkat keberhasilan tertentu, sering muncul dorongan untuk menambahkan API dengan alasan harus menjadi platform dan menarik developer
- Penyedia API harus terus melakukan kompromi antara penambahan fitur dan kompatibilitas/interoperabilitas, dan kebebasan untuk berubah jadi sangat berkurang karena perilaku serta karakteristik performa yang sudah ada
- Adanya API tidak berarti pasti ada orang yang ingin menggunakannya
- API baru sering muncul ketika produk menginginkan suatu kemampuan tetapi tidak memberi prioritas internal yang cukup tinggi
- Pasar sasarannya mungkin kecil, sangat vertikal, atau terbatas pada domain tertentu, sehingga berharap mitra eksternal akan menutup celah lewat API
- Namun mitra semacam itu juga punya bisnis dan pelanggan mereka sendiri, sehingga mereka mungkin tidak ingin menambahkan produk lain hanya untuk menyelesaikan masalah tersebut
- Menjadi platform adalah bisnis dengan tuntutan nyata yang besar, dan jarang hanya dengan menyediakan beberapa API pihak ketiga langsung punya dasar ekonomi untuk membangun di atasnya
“Mari tambah satu lapisan abstraksi lagi”
- Ucapan Butler Lampson bahwa “semua masalah dalam ilmu komputer bisa diselesaikan dengan satu lapisan indirection lagi” memang mengandung kebenaran nyata
- Kegagalan biasanya muncul dalam dua bentuk
- Abstraksi yang dimasukkan terlalu dini akan tertinggal di arsitektur sebagai abstraksi berlebihan tanpa rencana penggunaan yang nyata
- Abstraksi yang ditambahkan belakangan dapat membuat pemeliharaan, keamanan, dan optimisasi performa menjadi sangat rumit
- Windows NT memiliki banyak abstraksi berlebihan yang dimasukkan sejak awal tetapi pada praktiknya tidak pernah digunakan
- Dalam evolusi Mac OS, ada kasus ketika abstraksi yang awalnya tampak aneh justru menjadi berguna dua rilis kemudian, dan perbedaannya adalah adanya perencanaan
- Jika abstraksi yang ditambahkan belakangan hanya dipakai di sebagian kode, maka akan semakin banyak kode yang tidak memakai abstraksi baru itu sehingga beban pemeliharaan meningkat
“Mari buat jadi asinkron”
- Sebagian besar dari 25 tahun awal ilmu komputer dihabiskan untuk memahami dan mengimplementasikan perilaku asinkron
- Pada program pascasarjana tahun 1980-an, topik seperti dining philosophers, producer-consumer, dan sleeping barber dibahas cukup lama
- Saat ini banyak engineer menangani masalah asinkron dalam bentuk yang sudah cukup diabstraksikan berkat aturan lapisan data dan framework web
- Jika Anda mengelola asinkron secara langsung di luar framework atau lapisan data, awalnya mungkin terlihat berjalan baik, lalu setahun kemudian muncul bug yang sulit direproduksi
- Yang bisa dilakukan hanyalah berharap bug itu bukan masalah korupsi data
“Kontrol akses kita tambahkan nanti”
- Letak kontrol akses dulu merupakan bahan perdebatan teoretis, tetapi sekarang sistem berada dalam lingkungan yang jauh lebih kompleks karena terus-menerus diserang
- Semua orang tahu sejak awal bahwa keamanan itu perlu, tetapi karena dorongan untuk cepat masuk pasar, hampir tidak ada sistem yang merancang kontrol akses dan model keamanan secara sepenuhnya dari awal
- Jika tidak berangkat dari sudut pandang pelanggan dan penyerang, akan sulit membuat rancangan kontrol akses yang sesuai dengan produk
- Menempelkan kontrol akses di belakang sering kali gagal, atau berujung pada situasi ketika produk harus ditulis ulang di kemudian hari
- Penulisan ulang seperti itu menjadi pengalaman yang buruk bagi semua pihak, termasuk pelanggan
“Mari sinkronkan datanya”
- Dalam lingkungan dengan banyak perangkat, aplikasi SaaS, dan penyimpanan data, usulan “mari sinkronkan datanya saja” sering muncul
- Seperti ditekankan Ray Ozzie, pelopor client/server dan sinkronisasi data, sinkronisasi adalah masalah yang sulit
- Dalam ilmu komputer, masalah yang sulit berarti tantangan yang sering hanya bisa dipelajari lewat pengalaman dan sangat rumit untuk ditangani
- Bahkan pada penyimpanan data dengan semantik penuh dan transaksi lengkap, sinkronisasi tetap sulit; ketika blob, data tak terstruktur, dan transformasi data ikut masuk, tingkat kesulitannya naik tajam
- Menjadikan sinkronisasi data sebagai fondasi solusi hampir tidak pernah menjadi pilihan yang diinginkan, dan inilah juga alasan ada perusahaan bernilai miliaran dolar yang hanya berfokus pada sinkronisasi
“Mari buat cross-platform”
- Cross-platform adalah perdebatan yang terus berulang sejak lama, dan selalu ada yang berkata kode buatannya berjalan baik atau mencontohkan Unity dan game
- Ketika Anda mengatakan akan membuat sesuatu menjadi cross-platform, pada praktiknya itu hampir sama dengan berjanji untuk membuat salah satu dari sistem operasi, penyedia cloud, atau browser
- Cross-platform bekerja dengan baik dalam dua kasus
- Saat platform masih baru dan sederhana, misalnya ketika cloud masih sebatas komputasi dan storage sederhana
- Saat aplikasi atau produk masih baru dan sederhana
- Kondisi ini runtuh ketika Anda mulai menyimpang dari platform dasar, atau mulai membuat fitur yang direpresentasikan dengan cara yang sama sekali berbeda di tiap platform target
- Microsoft kesulitan membuat Office untuk Mac dan Office untuk Windows dengan basis kode yang sama, lalu mem-fork kode Office pada 1998 dan tidak pernah kembali lagi
- Microsoft awalnya memang hidup dari bisnis membuat aplikasi cross-platform, tetapi itu terjadi pada masa ketika dokumentasi API OS hanya sekitar 100 halaman dan tiap OS masih merupakan turunan dari CP/M
- Tulisan terkait: Divergent Thoughts on Cross Platform
“Kalau perlu, beri jalan keluar ke native”
- Karena cross-platform biasanya hanya bekerja baik untuk waktu yang singkat, abstraksi framework dan API sering menyediakan native escape
- Gagasan ini adalah membiarkan platform native dipanggil langsung ketika platform berkembang dan framework belum mengekspos fitur tersebut
- Namun framework atau API yang menyediakan abstraksi juga memelihara state internal atau cache
- Jika platform native dipanggil langsung, struktur data dan state dapat berubah tanpa diketahui framework
- Beberapa framework menyediakan mekanisme untuk bertukar data atau state antara kode escape dan framework, tetapi solusinya terasa mirip dengan menghidupkan kembali arsitektur seperti malloc/free di era manajemen memori otomatis
Bisa dipilih, tetapi bukan default
- Ini bukan berarti pendekatan-pendekatan tersebut harus selalu dijawab dengan “tidak”
- Dalam konteks tertentu, cara-cara ini bisa berhasil
- Namun dalam kebanyakan kasus, pola seperti ini tidak diperlukan atau ada cara yang lebih baik
- Daripada lebih dulu mengambil pola perangkat lunak yang peluang gagalnya tinggi, lebih baik menyelesaikan masalah dari prinsip pertama
2 komentar
Untuk plugin, yang paling penting adalah merancang antarmuka dengan menyaring tindakan yang benar-benar esensial sebanyak mungkin.
Jika antarmuka dibuat dengan cara sekadar meniru struktur dari kode saat ini, tentu saja akan menghasilkan antarmuka yang tidak perlu dan terikat pada implementasi tersebut, dan ini memang sering sekali terjadi...
Komentar Hacker News
Masalah dari ide-ide seperti ini bukan pada idenya sendiri, melainkan pada pendekatan “coba jalanin saja” atau ekspektasi yang melekat di depannya
Misalnya, jika melihat API sebagai “sekadar satu fitur” dalam produk, seperti “tambahkan API saja”, tingkat keberhasilannya mungkin mirip dengan “tambahkan UI saja”
Untuk membuat UI yang baik, kita harus cermat dan menyeluruh, dan juga membutuhkan pakar di bidang itu
Tidak ada alasan mengapa antarmuka lain dari sebuah produk harus berbeda; intinya bukan apakah itu ide buruk atau ide bagus, melainkan bahwa ini bukan sesuatu yang boleh dilakukan asal-asalan
Satu-satunya orang yang boleh mengatakan “sekadar” adalah developer yang benar-benar bertanggung jawab membuatnya berjalan, dan jika developer lain mengatakannya, itu berarti ia secara sukarela mengambil pekerjaan tersebut
Aturan itu cocok untuk kami
Untuk membuat API dengan benar, dibutuhkan banyak desain dan kompleksitas
Jika tidak dirancang dengan baik, klien harus melakukan beberapa panggilan untuk sesuatu yang seharusnya cukup sekali, atau API-nya membingungkan sehingga dipanggil dengan cara yang salah, atau bahkan tidak bisa digunakan sama sekali
Autentikasi dan otorisasi juga diperlukan, jadi harus menyiapkan OAuth2 atau setidaknya ada pembuatan, penyimpanan, dan verifikasi token API yang aman
Data juga harus ditangani dengan aman, dan jika performanya buruk, database bisa kewalahan oleh beban
Jika menambahkan caching, akan muncul kompleksitas tambahan berupa invalidasi cache serta server dan proses pendukung cache
Tanpa rate limiting, klien yang ceroboh bisa menghantam API terus-menerus, dan jika dokumentasinya buruk, API itu pada dasarnya tidak berguna
Dalam beberapa kasus, perlu juga menyediakan SDK untuk berbagai bahasa, dan tanpa pesan error yang baik, pengguna pertama kali tidak akan tahu mengapa panggilannya gagal
Orang menggeneralisasi hal yang pernah berjalan buruk bagi mereka, tetapi kecuali Anda adalah orang yang sama dalam situasi yang sangat mirip, nasihat itu hampir tidak bisa diterapkan begitu saja
Nasihat yang konsisten benar biasanya terlalu umum, seperti “pikirkan dengan hati-hati, berusahalah melakukan hal yang benar, dan tinjau hasilnya”, sehingga nyaris tidak berguna
Ucapan seperti itu juga tidak banyak menjual posting blog maupun buku
Karena perlu memastikan pelanggan tidak ketakutan saat kita mulai mengangkat sisa gunung es ke atas permukaan air
Dengan begitu, tulisannya bukan soal mungkin atau tidak mungkin, melainkan tentang cara sesuatu berhasil atau gagal
Setelah mengetahui detail yang diperlukan, akan lebih sulit mengatakan “sekadar” tanpa tahu apa yang tidak kita ketahui
Namun soal DSL, saya hampir 100% setuju
Itu cenderung menjadi komplikasi yang tidak perlu dan sok manis; orang yang layak membuatnya setidaknya harus seseorang yang pernah membuat bahasa pemrograman yang sukses, memperbaruinya sampai edisi kedua atau bahkan bahasa kedua dengan memasukkan pelajaran dari kesalahan, tetapi tetap masih salah dalam banyak hal
(1) DSL kadang bekerja dengan sangat baik. Lihat https://www.jooq.org/
(2) Elastic Load Balancer adalah loop kontrol yang bereaksi terhadap beban kerja, dan teknologi semacam ini sudah menjadi teknologi umum
(3) Di sebagian besar industri, under-provisioning sangat lazim. Lihat https://erikbern.com/2018/03/27/waiting-time-load-factor-and... dan https://www.amazon.com/Goal-Process-Ongoing-Improvement/dp/0...
(4) Deteksi anomali tidak secara inheren merupakan masalah sistem terdistribusi seperti item-item lainnya, tetapi orang yang pernah benar-benar kena batunya mungkin merasa itu diperlukan
Ini juga bidang yang sulit secara intelektual
Algoritme pertama yang membuat saya merasa cukup pintar adalah https://scikit-learn.org/1.5/modules/outlier_detection.html#..., dan kadang bekerja seperti keajaiban
Saat diterapkan pada teks dengan embedding berbasis CNN yang saya pakai pada 2018, hasilnya cocok, tetapi dengan SBERT sama sekali tidak beruntung
Keduanya memecahkan masalah dan tidak ada yang mengumpat
Faktor terpentingnya tampaknya karena keduanya kecil
Keduanya sangat mirip dan kodenya juga digunakan ulang
Yang satu untuk menulis aturan validasi formulir raksasa, yang lain untuk menulis aturan pengambilan keputusan berdasarkan respons formulir
DSL yang baik membuat orang yang tadinya tidak bisa menjadi bisa
DSL yang dibuat untuk menghemat waktu jauh lebih kecil kemungkinannya berguna, karena besar kemungkinan ia tidak benar-benar menghemat waktu
Dalam kedua kasus, perilaku domain yang kompleks harus dibawa ke dalam program
Jadi pilihannya adalah mengajari programmer tentang domain, memasangkan programmer dengan pakar domain, atau mengajari pakar domain pemrograman
Kalau pekerjaannya banyak, memberi kekuatan ke tangan pakar domain terasa menarik
Programmer bisa mengerjakan hal lain dan loop umpan balik juga menjadi lebih pendek
Jika domainnya dalam, Anda mungkin tidak ingin mengirim programmer ke sekolah untuk mempelajarinya; jika domainnya dangkal, orang yang lebih murah mungkin bisa menanganinya
DSL membawa beban kognitif yang besar
Namun jika alternatifnya adalah mempelajari bahasa pemrograman penuh, itu menjadi lebih masuk akal
DSL untuk menghemat waktu biasanya adalah kasus ketika orang yang sudah bisa menulis kode ingin menulis lebih sedikit kode, tetapi penghematannya kecil sehingga umumnya kurang bagus
Lalu ketika programmer ingin mengubah sesuatu, alih-alih kode yang intuitif, ia harus mempelajari atau mengingat seluruh DSL ini
Sebagai aturan praktis yang lebih sederhana, DSL untuk programmer lebih kecil kemungkinannya menjadi ide bagus dibanding DSL untuk non-programmer
Menulis kueri SQL, mengujinya di alat seperti DataGrip, lalu menghabiskan berjam-jam mencari cara mengubahnya menjadi DSL
Masalahnya makin parah saat memakai fitur SQL yang “eksotis” seperti ekspresi JSON
Debugging menjadi alur “cetak SQL yang dihasilkan, salin ke tempat seperti DataGrip, tuning kuerinya, lalu cari cara memasangkannya kembali ke DSL”
Ini pemborosan waktu yang luar biasa
Nilai jual utama jOOQ adalah kueri type-safe, tetapi ketika IntelliJ mulai memvalidasi SQL string di dalam kode terhadap data nyata, pentingnya hilang
Alur mengedit SQL langsung dan mengujinya langsung ke database memang lebih baik
jOOQ justru memperkuat argumen tulisan asli tentang DSL
Contoh DSL populer yang bisa dianggap buruk atau mendekati gagal antara lain HCL, E4X, XUL, dan bahasa pemformatan string milik Common Lisp
HCL adalah bahasa konfigurasi Terraform, dan jelas sejak awal ia tidak menangani masalah yang sangat umum, yaitu mem-provision perangkat serupa sebanyak jumlah variabel
Upaya menambahkan fitur belakangan juga canggung dan tidak sepenuhnya menyelesaikan masalah
E4X adalah DSL JavaScript untuk bekerja dengan XML; untuk kasus sederhana ia membuat pekerjaan XML bisa diekspresikan lebih ringkas, tetapi bisa cepat berubah menjadi dinding tanda baca yang sulit dibaca
Mirip juga dengan LINQ dari Microsoft, ia sama sekali tidak memberi tahu penulisnya seberapa besar kompleksitas komputasi kode internalnya
Pada akhirnya, kode yang memakai DSL ini sering ditulis ulang dengan cara yang kurang ringkas tetapi lebih mudah dianalisis
XUL adalah bahasa UI untuk ekstensi chrome browser Firefox, dan untuk tujuan membuat ekstensi Firefox itu cukup baik
Namun Firefox juga ingin menjualnya sebagai teknologi dasar untuk aplikasi internal perusahaan, dan di area itu ia sangat kurang
Untuk melakukan hal sederhana diperlukan banyak trik dan jalan memutar
Bahasa pemformatan string Common Lisp juga serupa: baik untuk masalah kecil, tetapi tidak skalabel
Beberapa masalah pemformatan memerlukan solusi yang sangat aneh atau sejak awal memang tidak ada jawabannya, dan saya benar-benar tidak suka melihat kode yang memanggil
formatsecara rekursifSecara keseluruhan, masalah paling umum dari pendekatan seperti ini adalah sifatnya tambal sulam dan tidak berkembang dengan baik
Anda akan segera bertemu masalah yang tidak bisa diselesaikan dengan benar, dan program besar yang ditulis dengan DSL sering kali menjadi mimpi buruk untuk ditangani
Jika menaruh DSL di atas Lisp, yang perlu ditulis hanyalah logika domain, bukan bahasa dasarnya
Sebagian besar pekerjaan sudah selesai, dan bahasanya berguna sejak hari pertama
Jika dibuat sebagai DSL yang di-host di atas Lisp, ia bisa benar-benar dipakai; saya tidak mengerti mengapa harus membuat bahasa baru dari nol lalu menyaksikannya layu dan mati
Semua butir ini punya banyak kisah sukses
Sulit memakai kata “hampir” sebagai jalan keluar
Ini terlihat seperti pesimisme dan sinisme yang letih belaka
Saya memahami perasaan itu dan pernah merasakannya juga, dan kadang memang sulit membuat engineer yang antusias meninggalkan ide buruk
Namun nuansa seperti ini terasa berbahaya bagi saya
Control loop yang lepas kendali menuju tak hingga atau batas maksimum/minimum, cache yang gagal pulih dari kegagalan terdistribusi, state yang rusak saat live migration, burst yang menyebabkan overload pada saat yang tidak nyaman, peringatan deteksi anomali palsu tentang hari libur di seluruh dunia, dan semacamnya
Di bawah semua ide itu ada jalinan kompleksitas yang hampir semua orang remehkan
Ini adalah daftar ide sistem yang lebih sulit daripada perkiraan awal, dan harus didekati dengan serius, bukan dianggap enteng
Sekilas terdengar mirip dengan “terlihat bagus tetapi hampir tidak pernah bekerja”, tetapi detailnya sama sekali berbeda
Jika diperlakukan sebagai masalah sulit dan diinvestasikan sesuai itu, membuatnya bekerja dengan baik adalah hasil yang biasa-biasa saja dan dapat dicapai
Jika menjadi fitur tempelan setelahnya atau dianggap naif mudah, sering kali hasilnya salah
Saya membacanya sebagai cerita tentang para engineer yang terpaku pada optimasi prematur meski tidak ada manfaat bisnisnya
Ini benar-benar merajalela di industri, karena menyenangkan merancang dan membuat kapal antariksa auto-scaling redundan untuk sesuatu yang biayanya mungkin kurang dari sepersepuluh jika cukup menyiapkan backup yang bisa di-deploy dalam beberapa jam dan melakukan over-provisioning server 200%
Ada kalanya ide seperti ini valid, tetapi itu setelah kebutuhannya muncul
Bukan sesuatu yang perlu dirancang sejak tahap produk awal
Sangat jarang ada produk yang benar-benar membutuhkan skala, ketersediaan, dan kompleksitas yang hendak dipecahkan oleh implementasi seperti ini
Banyak orang di sini tampaknya berusaha mencari fungsi penilaian yang halus untuk memisahkan pengecualian, padahal sebenarnya sederhana
Ide-ide ini hebat kalau saya yang melakukannya, dan tidak akan pernah bekerja sesuai maksud jika dilakukan oleh orang bodoh sebelum saya
Dan kadang orang bodoh sebelum itu adalah diri saya sendiri beberapa bulan lalu
Saya juga ingin menambahkan domain-driven design ke sini
Mencoba menyelaraskan aplikasi dengan struktur bisnis sambil mengunci desain bisnis adalah resep menuju bencana
Jika bisnisnya kecil atau stagnan, masalahnya mungkin tidak terasa
Namun jika bisnis berhasil atau tumbuh, Anda akan segera menyesal pernah mencoba membuat domain dengan nama-nama yang sangat deskriptif tetapi sudah terikat pada praktik kerja yang usang
Sebaliknya, jauh lebih fleksibel merancang berpusat pada lapisan fungsional seperti cara yang telah teruji selama puluhan tahun, dan sejauh mungkin menaruh business logic di konfigurasi, baris database, dan workflow pengguna
Anda menyebut jebakan domain-driven design berupa bahasa yang usang dan rendahnya reuse kode/sistem untuk upaya baru; sebaliknya, desain yang sangat abstrak yang menaruh business logic di konfigurasi, workflow, dan lain-lain juga hanya fleksibel jika seluruh organisasi memahami abstraksi, konfigurasi, dan kombinasi tak terhitung itu dengan cukup baik
Kombinasi itu cepat meledak seperti labirin, menciptakan perilaku yang tidak diketahui dan tidak terduga yang kemudian diandalkan orang
Biaya onboarding developer baru dan pergantian tim pengembang juga menjadi sulit ditanggung
Organisasi mulai berbicara dalam dua bahasa berbeda
Sebagian besar permintaan fitur yang tampak sederhana, jika memecahkan abstraksi, berubah menjadi perancangan ulang sistem besar, atau menjadi “mari kita hack saja abstraksi ini agar sekarang terlihat seperti perubahan yang lebih aman dan kecil”
Yang pertama selalu sangat sulit bahkan dengan engineer hebat yang benar-benar memahami perilaku seluruh sistem dan codebase, serta praktik dan proses engineering yang baik, dan bisa memakan waktu berbulan-bulan atau bertahun-tahun
Yang kedua lebih sering terjadi, sehingga proyek yang “sangat diabstraksikan, dilapisi secara fungsional, berbasis konfigurasi, dan business logic-nya muncul secara emergen” awalnya tampak sempurna dan fleksibel, tetapi akhirnya menjadi “ini apaan sih”
Setelah sistem diimplementasikan, business logic emergen itulah yang menjadi bahasa yang dibicarakan semua orang
Jika organisasi berbicara dalam dua atau tiga bahasa yang sama sekali tidak dapat didamaikan, itu sangat menyakitkan; dan jika tidak ada beberapa orang yang fasih menerjemahkan di antara semuanya ke atas, ke bawah, dan ke samping, Anda akan merasa seharusnya domain diekspresikan lebih dekat sejak awal
Jika Anda merancang agar suatu state tidak dapat direpresentasikan oleh tipe, Anda harus yakin bahwa selama umur desain itu, state tersebut benar-benar state yang mustahil
Saya kurang paham dengan butir control loop yang bereaksi terhadap beban
Itu adalah komponen dasar dan fundamental dari banyak sekali sistem
Governor sentrifugal pada mesin uap tahun 1800-an atau pemutar piringan hitam Victrola tahun 1900-an juga merupakan control loop yang bereaksi terhadap beban
Seluruh elektronika adalah jaringan control loop yang bereaksi terhadap beban, begitu pula transmisi otomatis mobil
Penggunaan CPU adalah contoh yang menarik
Misalnya, kita bisa melihat situasi ketika load balancer lintas region bertarung dengan load shedding di dalam proses
Karena sinyal load balancer tidak mencerminkan load shedding, atau cara mencerminkannya tidak akurat
Masalah lain adalah ketika control loop yang mencoba mengoptimalkan hasil lokal suatu layanan justru merusak hasil keseluruhan
Secara umum, saya pikir lebih baik menempatkan sedikit control loop di posisi yang berdampak besar
Beban CPU punya beberapa masalah seperti yang dijelaskan di https://arxiv.org/abs/2312.10172
Ada pola umum dalam masalah-masalah ini
Semuanya adalah concern ortogonal yang menambahkan batasan pada model pemrograman pemrosesan data sekuensial yang akrab bagi programmer
Setiap kali menambahkan batasan, bertambah pula hal yang harus terus dipikirkan oleh semua pengembang berikutnya selama mereka mengembangkan sistem itu ke depannya
Sistem mudah menjadi terlalu dibatasi hingga terjebak dalam situasi di mana tidak bisa maju kecuali sebagian batasan dilonggarkan
Kalaupun bukan mustahil, prosesnya menjadi lambat
Sebab pengembang setiap kali harus mempertimbangkan bagaimana fitur baru berinteraksi dengan API, keamanan, sinkronisasi, latensi, platform lain, dan kode native yang sudah dijanjikan untuk didukung
Jadi mendukung semua properti ini juga memang mungkin
Misalnya, jika sinkronisasi data transparan dijadikan proposisi nilai inti platform, maka semua pengembangan berikutnya akan memprioritaskan dukungan untuk itu dan mengembangkan kumpulan fitur yang mungkin dalam batasan tersebut
Kumpulan fitur itu mungkin tidak persis sama dengan yang diinginkan pengguna, tetapi itulah cakupan yang didukungnya
Produk akan terlihat menarik bagi pelanggan yang menempatkan properti itu sebagai prioritas utama dalam keputusan pembelian
Saya pernah mengerjakan proyek yang memakai beberapa DSL, cache P2P, dan paralelisme campuran, dan semuanya berjalan
Membuatnya juga benar-benar menyenangkan
Dengan satu pengecualian, semuanya investasi yang bagus
Cache P2P pada akhirnya tidak banyak terbayar karena memang tidak diperlukan
Jadi jelas salah mengatakan hal-hal seperti ini hampir tidak pernah berhasil
Memang kompleks, tetapi kompleksitas itu menghadirkan fungsi yang sulit diperoleh dengan cara lain
Pelajaran dari contoh cache P2P adalah memastikan lebih dulu apakah fungsi itu benar-benar dibutuhkan
Karena saya pernah berhasil menjalankan cukup banyak dari ide-ide ini, bacanya terasa agak aneh
“Mari sinkronkan data saja” adalah alasan, menurut saya, hari-hari berat itu ada
Saya sudah terlalu sering melihat sistem yang menambahkan queue, pemrosesan event, dan semacamnya dengan membayangkan sesuatu seperti “skala internet”, padahal cakupan alaminya sebenarnya jauh di bawah ambang itu
Tim seperti ini entah naif, atau dalam skenario terburuk memanfaatkan manajemen yang tidak memahami engineering untuk menarik dana agar bisa bermain-main dengan masalah semacam ini demi kesenangan
Untuk melakukannya dengan benar, queue dan pemrosesan event memang wajib