Setiap hari, setiap saat selama karier teknik kami, kami menghadapi banyak masalah dengan berbagai kompleksitas dan situasi yang mengharuskan kami mengambil keputusan atau menundanya karena kurangnya data. Setiap kali kami membangun layanan baru, membangun infrastruktur, atau bahkan membentuk proses pengembangan, kami menghadapi berbagai tantangan yang sangat besar.
Sulit, dan mungkin bahkan mustahil, untuk mencantumkan semua masalah. Anda akan menemui beberapa masalah ini hanya jika Anda bekerja di bidang tertentu. Di sisi lain, ada banyak masalah yang harus kita semua pahami cara penyelesaiannya, karena masalah-masalah tersebut sangat penting dalam membangun sistem TI. Dengan kemungkinan besar, Anda akan menemuinya di semua proyek.
Dalam artikel ini, saya akan berbagi pengalaman saya dengan beberapa masalah yang saya temui saat membuat program perangkat lunak.
Jika kita melihat di Wikipedia, kita akan menemukan definisi berikut
Dalam pengembangan perangkat lunak berorientasi aspek, masalah lintas sektor adalah aspek program yang memengaruhi beberapa modul, tanpa kemungkinan dirangkum dalam salah satu modul. Masalah ini sering kali tidak dapat dipisahkan dengan jelas dari sistem lainnya baik dalam desain maupun implementasi, dan dapat mengakibatkan penyebaran (duplikasi kode), kekusutan (ketergantungan signifikan antar sistem), atau keduanya.
Ini menggambarkan dengan jelas apa itu, tetapi saya ingin memperluas dan menyederhanakannya sedikit:
Keprihatinan lintas sektor merupakan suatu konsep atau komponen sistem/organisasi yang mempengaruhi (atau 'melintasi') banyak bagian lainnya.
Contoh terbaik dari masalah tersebut adalah arsitektur sistem, pencatatan, keamanan, manajemen transaksi, telemetri, desain basis data, dan masih banyak lagi. Kami akan menguraikan banyak di antaranya nanti dalam artikel ini.
Pada level kode, masalah lintas sektor sering kali diimplementasikan menggunakan teknik seperti Aspect-Oriented Programming (AOP) , di mana masalah-masalah ini dimodularisasi menjadi komponen-komponen terpisah yang dapat diterapkan di seluruh aplikasi. Hal ini menjaga logika bisnis tetap terisolasi dari masalah-masalah ini, sehingga kode menjadi lebih mudah dibaca dan dipelihara.
Ada banyak cara yang memungkinkan untuk mengklasifikasikan aspek dengan mengelompokkannya berdasarkan properti yang berbeda seperti cakupan, ukuran, fungsionalitas, kepentingan, target, dan lain-lain, tetapi dalam artikel ini, saya akan menggunakan klasifikasi cakupan yang sederhana. Yang saya maksud dengan ini adalah ke mana aspek spesifik ini diarahkan, apakah itu keseluruhan organisasi, sistem tertentu, atau elemen tertentu dari sistem tersebut.
Jadi, saya akan membagi aspek menjadi Makro dan Mikro .
Yang saya maksud dengan aspek Makro adalah pertimbangan-pertimbangan yang kita terapkan pada keseluruhan sistem, seperti arsitektur sistem yang dipilih dan desainnya (monolitik, layanan mikro, arsitektur berorientasi layanan), tumpukan teknologi, struktur organisasi, dsb. Aspek makro terutama terkait dengan keputusan-keputusan strategis dan tingkat tinggi.
Sementara itu, aspek Mikro lebih dekat dengan level kode dan pengembangan. Misalnya, kerangka kerja mana yang digunakan untuk berinteraksi dengan basis data, struktur folder dan kelas proyek, atau bahkan pola desain objek tertentu.
Meskipun klasifikasi ini tidak ideal, klasifikasi ini membantu menyusun pemahaman tentang kemungkinan masalah dan pentingnya serta dampak solusi yang kita terapkan pada masalah tersebut.
Dalam artikel ini, fokus utama saya akan tertuju pada aspek makro.
Ketika saya baru mulai belajar tentang arsitektur perangkat lunak, saya membaca banyak artikel menarik tentang hukum Conway dan dampaknya terhadap struktur organisasi. Terutama yang satu ini . Jadi, hukum ini menyatakan bahwa
Setiap organisasi yang merancang suatu sistem (didefinisikan secara luas) akan menghasilkan desain yang strukturnya merupakan salinan dari struktur komunikasi organisasi.
Saya selalu percaya bahwa konsep ini memang sangat universal dan mewakili Aturan Emas.
Kemudian saya mulai mempelajari pendekatan Domain-Driven Design (DDD) milik Eric Evans untuk memodelkan sistem. Eric Evans menekankan pentingnya identifikasi Konteks Terbatas. Konsep ini melibatkan pembagian model domain yang kompleks menjadi beberapa bagian yang lebih kecil dan lebih mudah dikelola, yang masing-masing memiliki pengetahuan yang terbatas. Pendekatan ini membantu komunikasi tim yang efektif, karena mengurangi kebutuhan akan pengetahuan yang luas tentang seluruh domain dan meminimalkan peralihan konteks, sehingga membuat percakapan menjadi lebih efisien. Peralihan konteks adalah hal terburuk dan paling menghabiskan sumber daya. Bahkan komputer pun kesulitan mengatasinya. Meskipun tidak mungkin mencapai ketiadaan peralihan konteks sepenuhnya, saya rasa itulah yang harus kita perjuangkan.
Kembali ke Hukum Conway, saya menemukan beberapa masalah dengannya.
Masalah pertama yang saya temui dengan Hukum Conway, yang menyatakan bahwa desain sistem mencerminkan struktur organisasi, adalah potensi untuk membentuk Konteks Terbatas yang kompleks dan komprehensif. Kompleksitas ini muncul ketika struktur organisasi tidak selaras dengan batasan domain, yang mengarah ke Konteks Terbatas yang sangat saling bergantung dan sarat dengan informasi. Hal ini menyebabkan seringnya terjadi pergantian konteks bagi tim pengembangan.
Masalah lainnya adalah bahwa terminologi organisasi bocor ke tingkat kode. Ketika struktur organisasi berubah, hal itu memerlukan modifikasi basis kode, yang menghabiskan sumber daya yang berharga.
Dengan demikian, mengikuti Inverse Conway Maneuver membantu membangun sistem dan organisasi yang mendukung arsitektur perangkat lunak yang diinginkan. Akan tetapi, perlu dicatat bahwa pendekatan ini tidak akan bekerja dengan baik dalam arsitektur dan struktur yang sudah terbentuk karena perubahan pada tahap ini bersifat jangka panjang, tetapi sangat efektif dalam perusahaan rintisan karena mereka cepat dalam memperkenalkan perubahan apa pun.
Pola atau "anti-pola" ini mendorong pembangunan sistem tanpa arsitektur apa pun. Tidak ada aturan, tidak ada batasan, dan tidak ada strategi tentang cara mengendalikan kompleksitas yang tak terelakkan. Kompleksitas adalah musuh yang paling tangguh dalam perjalanan membangun sistem perangkat lunak.
Untuk menghindari pembangunan sistem jenis seperti itu, kita perlu mengikuti aturan dan batasan khusus.
Ada banyak sekali definisi untuk Arsitektur Perangkat Lunak. Saya menyukai banyak definisi karena mencakup berbagai aspeknya. Akan tetapi, untuk dapat bernalar tentang arsitektur, kita perlu secara alami membentuk beberapa definisi di dalam pikiran kita. Dan perlu dicatat bahwa definisi ini dapat berkembang. Jadi, setidaknya untuk saat ini, saya memiliki deskripsi berikut untuk diri saya sendiri.
Arsitektur Perangkat Lunak adalah tentang keputusan dan pilihan yang Anda buat setiap hari yang memengaruhi sistem yang dibangun.
Untuk membuat keputusan, Anda perlu memiliki prinsip dan pola dalam "tas" Anda untuk memecahkan masalah yang timbul, penting juga untuk menyatakan bahwa memahami persyaratan adalah kunci untuk membangun apa yang dibutuhkan bisnis. Namun, terkadang persyaratan tidak transparan atau bahkan tidak didefinisikan, dalam hal ini, lebih baik menunggu untuk mendapatkan klarifikasi lebih lanjut atau mengandalkan pengalaman Anda dan memercayai intuisi Anda. Namun, bagaimanapun, Anda tidak dapat membuat keputusan dengan benar jika Anda tidak memiliki prinsip dan pola untuk diandalkan. Di situlah saya sampai pada definisi Gaya Arsitektur Perangkat Lunak.
Gaya Arsitektur Perangkat Lunak adalah serangkaian prinsip dan pola yang menentukan cara membangun perangkat lunak.
Ada banyak gaya arsitektur berbeda yang difokuskan pada berbagai sisi arsitektur yang direncanakan, dan menerapkan beberapa di antaranya sekaligus adalah situasi yang normal.
Misalnya saja seperti:
Arsitektur monolitik
Desain berbasis domain
Berbasis komponen
Layanan mikro
Pipa dan filter
Berbasis pada peristiwa
Mikrokernel
Berorientasi pada layanan
dan sebagainya…
Tentu saja, mereka memiliki kelebihan dan kekurangan, tetapi hal terpenting yang saya pelajari adalah bahwa arsitektur berevolusi secara bertahap sambil bergantung pada masalah aktual. Memulai dengan arsitektur monolitik adalah pilihan yang bagus untuk mengurangi kompleksitas operasional, kemungkinan besar arsitektur ini akan sesuai dengan kebutuhan Anda bahkan setelah mencapai tahap Product-market Fit (PMI) dalam membangun produk. Dalam skala besar, Anda dapat mempertimbangkan untuk beralih ke pendekatan berbasis peristiwa dan layanan mikro untuk mencapai penerapan independen, lingkungan tumpukan teknologi heterogen, dan arsitektur yang kurang terhubung (dan kurang transparan untuk sementara waktu karena sifat pendekatan berbasis peristiwa dan pub-sub jika ini diadopsi). Kesederhanaan dan efisiensi dekat dan memiliki dampak besar satu sama lain. Biasanya, arsitektur yang rumit memengaruhi kecepatan pengembangan fitur baru, mendukung dan memelihara yang sudah ada, dan menantang evolusi alami sistem.
Akan tetapi, sistem yang kompleks sering kali memerlukan arsitektur yang kompleks dan komprehensif, yang tidak dapat dihindari.
Ini adalah topik yang sangat luas, dan ada banyak ide hebat tentang cara menyusun dan membangun sistem untuk evolusi alami. Berdasarkan pengalaman saya, saya telah menyusun pendekatan berikut:
Penting juga untuk memahami angka dan metrik seperti DAU (Pengguna Aktif Harian), MAU (Pengguna Aktif Bulanan), RPC (Permintaan Per Detik), dan TPC (Transaksi Per Detik) karena ini dapat membantu Anda membuat pilihan karena arsitektur untuk 100 pengguna aktif dan 100 juta pengguna aktif berbeda.
Sebagai catatan akhir, saya akan mengatakan bahwa arsitektur memiliki dampak yang signifikan terhadap keberhasilan produk. Arsitektur yang dirancang dengan buruk untuk produk diperlukan dalam penskalaan, yang kemungkinan besar mengarah pada kegagalan karena pelanggan tidak akan menunggu saat Anda menskalakan sistem, mereka akan memilih pesaing, jadi kita harus berada di depan potensi penskalaan. Meskipun saya akui bahwa terkadang itu bukan pendekatan yang ramping, idenya adalah memiliki sistem yang dapat diskalakan tetapi belum diskalakan. Di sisi lain, memiliki sistem yang sangat rumit dan sudah diskalakan tanpa pelanggan atau rencana untuk mendapatkan banyak pelanggan akan menghabiskan uang Anda untuk bisnis Anda tanpa hasil.
Memilih tumpukan teknologi juga merupakan keputusan tingkat makro karena memengaruhi perekrutan, perspektif evolusi alami sistem, skalabilitas, dan kinerja sistem.
Berikut adalah daftar pertimbangan dasar untuk memilih tumpukan teknologi:
Bagaimana memiliki berbagai tumpukan teknologi dapat memengaruhi pertumbuhan bisnis?
Dari satu perspektif, memperkenalkan satu tumpukan lagi dapat meningkatkan skala perekrutan Anda, tetapi di sisi lain, hal itu akan menimbulkan biaya pemeliharaan tambahan karena Anda perlu mendukung kedua tumpukan tersebut. Jadi, seperti yang saya katakan sebelumnya, menurut sudut pandang saya, hanya kebutuhan tambahan yang seharusnya menjadi argumen untuk menggabungkan lebih banyak tumpukan teknologi.
Tetapi bagaimana dengan prinsip pemilihan alat terbaik untuk masalah tertentu?
Terkadang Anda tidak punya pilihan lain selain menghadirkan alat baru untuk memecahkan masalah tertentu berdasarkan pertimbangan yang sama yang disebutkan di atas, dalam kasus seperti itu, masuk akal untuk memilih solusi terbaik.
Penciptaan sistem tanpa keterkaitan yang tinggi dengan teknologi tertentu bisa menjadi tantangan. Namun, akan sangat membantu jika kita mengupayakan kondisi di mana sistem tidak terlalu erat kaitannya dengan teknologi, dan sistem tidak akan mati jika besok, kerangka kerja atau alat tertentu menjadi rentan atau bahkan tidak digunakan lagi.
Pertimbangan penting lainnya terkait dengan ketergantungan perangkat lunak sumber terbuka dan perangkat lunak berpemilik. Perangkat lunak berpemilik memberi Anda lebih sedikit fleksibilitas dan kemungkinan untuk disesuaikan. Namun, faktor yang paling berbahaya adalah ketergantungan pada vendor, di mana Anda menjadi tergantung pada produk, harga, ketentuan, dan peta jalan vendor. Ini bisa berisiko jika vendor mengubah arah, menaikkan harga, atau menghentikan produk. Perangkat lunak sumber terbuka mengurangi risiko ini, karena satu entitas tidak mengendalikannya. Menghilangkan satu titik kegagalan di semua level adalah kunci untuk membangun sistem yang andal untuk pertumbuhan.
Titik kegagalan tunggal (SPOF) merujuk pada setiap bagian dari sistem yang, jika gagal, akan menyebabkan seluruh sistem berhenti berfungsi. Menghilangkan SPOF di semua tingkatan sangat penting untuk sistem apa pun yang membutuhkan ketersediaan tinggi. Segala hal, termasuk pengetahuan, personel, komponen sistem, penyedia cloud, dan kabel internet, dapat gagal.
Ada beberapa teknik dasar yang bisa kita terapkan untuk menghilangkan titik kegagalan tunggal:
Dalam artikel ini, kami membahas beberapa aspek Makro utama dan bagaimana kita dapat menangani kompleksitasnya.
Terima kasih telah membaca! Sampai jumpa di lain waktu!