Arsitektur sebagai beban

Selama karir saya, saya bekerja dengan berbagai proyek warisan, yang masing-masing menderita berbagai kekurangan.


Tentu saja, seringkali masalah utama adalah kualitas perangkat lunak yang buruk (kurangnya unit test, penolakan untuk menggunakan prinsip-prinsip kode bersih ...), tetapi ada juga kesulitan, yang sumbernya adalah keputusan arsitektur yang dibuat pada awal proyek atau bahkan selama awal sistem perusahaan. Menurut pendapat saya, kelas masalah ini adalah penyebab rasa sakit terbesar bagi banyak proyek.


Intinya, meningkatkan kode cukup mudah, terutama sekarang karena gerakan pengerjaan perangkat lunak mempromosikan praktik tim yang baik. Namun, mengubah bagian inti sistem, pembatasan yang diberlakukan pada awal siklus hidupnya, adalah tugas yang sangat sulit.


Saya akan memberi tahu Anda tentang beberapa jenis solusi arsitektur yang telah saya temui, yang dapat menjadi beban nyata bagi tim yang terlibat dalam mendukung sistem tersebut.



Seluruh perusahaan Anda membagikan basis data Anda


Ini mungkin salah satu masalah paling umum yang saya lihat. Ketika beberapa aplikasi perlu menggunakan data bersama, mengapa kita tidak memberikan mereka akses bersama ke database bersama? Lagi pula, duplikasi dianggap jahat dalam pengembangan perangkat lunak, bukan? Yah, ini tidak selalu benar, dan terutama ketika datang ke database. Venkat Subramaniam mengatakan seperti ini: "Basis datanya seperti sikat gigi: jangan pernah biarkan orang menggunakannya." Apa salahnya berbagi database? Padahal, cukup banyak ...


Hal pertama yang terlintas dalam pikiran adalah kopling model data. Bayangkan dua aplikasi, A dan B, memproses data pada mobil. Lampiran A digunakan oleh tim yang bertanggung jawab untuk pekerjaan perbaikan, dan oleh karena itu mereka perlu menyimpan banyak informasi teknis: tentang mekanik, kerusakan, riwayat intervensi dalam mobil ... Lampiran B digunakan untuk mengatur tugas-tugas untuk tim teknis, sehingga hanya memerlukan informasi dasar tentang mobil, cukup untuk identifikasi. Dalam hal ini, menggunakan struktur data yang sama untuk kedua program tidak masuk akal: mereka menggunakan data yang berbeda, sehingga masing-masing harus menggunakan struktur datanya sendiri. Ini dibuat lebih mudah karena mobil mudah diidentifikasi, sehingga tidak perlu untuk referensi umum.


Masalah kedua juga karena penyatuan model data ini. Bayangkan aplikasi B ingin mengganti nama pengenal mobil - berikan nama yang lebih logis dalam hal area subjeknya. Dalam hal ini, aplikasi A juga harus diperbarui - karena nama kolom telah berubah ... Akibatnya, agar tidak mengganggu aplikasi tim A, pengembang B akan mulai menggandakan informasi di kolom lain, karena mereka tidak dapat mengubah kolom yang ada ... Tentu saja, pengembang A akan mengatakan bahwa mereka berencana untuk mengubah nama kolom di masa depan agar tidak menyimpan informasi yang sama dalam dua kolom, tetapi kita semua tahu: kemungkinan besar ini tidak akan pernah dilakukan ...


Semuanya menjadi lebih menjijikkan ketika aplikasi tidak hanya membaca data dari satu sumber, tetapi juga mengubahnya! Siapa pemilik data dalam kasus ini? Siapa yang harus dipercaya? Bagaimana integritas data dapat dijamin? Ini sulit bahkan ketika data yang sama diubah oleh berbagai bagian aplikasi yang sama, tetapi ketika beberapa aplikasi berbeda melakukannya, masalahnya menjadi jauh lebih serius ...


Kasus terakhir yang saya lihat: dua aplikasi yang berbagi struktur data yang sama untuk menyimpan informasi tentang dua objek bisnis, relatif serupa, tetapi pada saat yang sama cukup berbeda sehingga menyulitkan pemahaman aplikasi mana yang dimaksud dengan data. Kedua aplikasi menggunakan tabel yang sama untuk memodelkan eksekusi di pasar keuangan, tetapi dengan tingkat agregasi yang berbeda. Tidak ada yang menunjukkan bahwa tabel tersebut berisi dua jenis data, jadi kami harus melihat tabel lain (milik aplikasi kedua) untuk menentukan baris yang dihasilkan oleh masing-masing program ... Setiap pengembang baru yang harus bekerja dengan tabel ini pasti datang pada penggaruk yang sama dengan semua pendahulunya, dan menggunakan data yang tidak benar (rentan), dengan semua risiko yang timbul dari ini untuk perusahaan.


Sistem Anda terkait dengan perangkat lunak yang digunakan di perusahaan


Tidak setiap perusahaan dapat mengembangkan perangkat lunak yang memenuhi semua kebutuhan bisnisnya. Bahkan, dalam banyak kasus ini akan menjadi penemuan sepeda, karena kebutuhan banyak perusahaan adalah sama, dan mudah untuk menemukan perangkat lunak di pasar yang sudah memiliki fungsi yang diperlukan.


Secara umum, sering kali lebih murah untuk membeli produk daripada membuatnya. Tetapi, tentu saja, produk yang baru saja Anda beli tidak langsung berfungsi mulus dengan perangkat lunak yang sudah Anda gunakan, jadi Anda perlu membuat jembatan antara dua (dalam kebanyakan kasus, kepemilikan) aplikasi. Anda pasti akan mengembangkan alat Anda sendiri untuk bagian-bagian spesifik dari bisnis Anda, dan selama perangkat lunak mahal yang telah Anda beli memiliki model yang sesuai, Anda hanya perlu menggunakan basis datanya dan menambahkan data Anda ke tabel basis data ini ...


Beberapa tahun berlalu, selusin pengembang atau tim melakukan tindakan ini berulang-ulang, dan kemudian Anda menemui jalan buntu: Anda tidak dapat menggunakan perangkat lunak lain jika pengembang perangkat lunak yang Anda beli menutupnya, atau berhenti mendukung produk, atau beberapa perangkat lunak baru ternyata lebih cocok untuk kebutuhan Anda. Dalam beberapa kasus, Anda bahkan mungkin memiliki ketergantungan teknis pada perangkat lunak eksternal. Jika pembuat solusi perangkat lunak yang Anda gunakan ingin Anda menggunakan versi bahasa / kerangka / sesuatu yang ia butuhkan, ini berarti bahwa arsitektur sistem Anda bukan milik Anda. Jika Anda ingin menjual versi baru untuk menyediakan fungsi yang pasti Anda butuhkan, tetapi versi ini dapat berubah persyaratan teknis, Anda akan dipaksa untuk memperbarui tumpukan teknologi Anda untuk memenuhi rekomendasi orang lain. Saya tahu bagaimana rasanya, dan Anda tidak ingin migrasi paksa seperti itu sering terjadi ...


Saya bekerja pada proyek di mana pengembang produk yang kami gunakan tidak ingin menambahkan fitur baru untuk semua pelanggan kami, karena terlalu sulit bagi mereka untuk mempertahankan perubahan kompetitif dan beberapa versi saat ini (setiap klien memiliki versi sendiri dengan fungsi yang hanya diperlukan untuknya). Jadi mereka memutuskan untuk menjual SDK kepada kami sehingga kami dapat mengimplementasikan fungsionalitas kami sendiri. Secara alami, mereka tidak memberikan dokumentasi yang cukup tentang bagaimana melakukan ini, dan, lebih lagi, kami terpaksa menggunakan entitas bisnis mereka, yang harus kami dekompilasi untuk memahami struktur mereka - karena kami tidak memiliki kode sumber, maupun dokumentasi ... Implementasi fungsional paling sederhana memakan waktu beberapa hari, dan hampir tidak mungkin untuk mengujinya, karena semuanya terlalu rumit, dan bahkan membutuhkan pengetahuan tentang bahasa scripting yang tidak diketahui oleh siapa pun dalam tim dengan tumpukan teknologi yang sudah rumit ...


Hubungan yang kuat antara berbagai aplikasi


Ingat awal 2000-an: betapa menyenangkannya menggunakan Enterprise Java Beans (EJB) untuk menangani panggilan jarak jauh antara aplikasi dalam sistem informasi Anda. Pada saat itu, ini mungkin ide yang bagus. Berbagi kode Anda dengan tim lain untuk menghindari duplikasi juga terlihat bagus. Ya, semua tim dipaksa untuk meluncurkan aplikasi mereka pada saat yang sama untuk memastikan bahwa dependensi biner tidak rusak, tapi itu menyenangkan di malam hari - makan pizza dengan rekan sambil menunggu aplikasi dikirimkan selama 2 jam, kan?


Sebenarnya itu tidak terlalu menyenangkan. Dan ketidakmungkinan refactoring kelas terpisah dalam kode Anda sendiri - hanya karena orang lain di perusahaan menyukai kode Anda dan mereka memutuskan untuk menggunakannya dalam aplikasi yang belum diuji - masih menyenangkan.


Begitu Anda menyadari betapa bingung keputusan awal ini, upaya yang diperlukan untuk memisahkan aplikasi Anda dari seluruh dunia sangat besar. Anda lihat, dalam arti literal, akan butuh bertahun-tahun untuk mengiris proyek Anda menjadi berbagai komponen sehingga aplikasi lain tidak lagi dapat menggunakan inti dari area subjek Anda, klien Anda atau mekanisme caching; untuk menghapus semua panggilan ke kelas eksternal yang mengarah ke hubungan yang kuat dengan proyek lain; untuk mengganti semua panggilan EJB dengan API REST ... Namun, untuk semua upaya ini, setiap karyawan yang terkait dengan proyek akan lebih dari dihargai: pengembangan dan pengujian akan disederhanakan, proses pengiriman akan dipercepat, karena sekarang tidak ada lagi kebutuhan untuk menyinkronkan pekerjaan mereka dengan orang lain ; konsep dalam kode Anda sendiri akan menjadi lebih baik dipisahkan; manajemen dependensi akan disederhanakan, masalah dengan dependensi transitif akan hilang ketika Anda mengimpor banyak dependensi aplikasi lain ke classpath Anda ... Semua perubahan yang mahal ini hanya akan menyelamatkan kehidupan tim dan mereka bisa lebih mudah diimplementasikan jika Anda membuatnya di awal proyek!


Anda membangun proyek Anda berdasarkan proyek orang lain


Anda kemungkinan besar tidak mengalami masalah ini, tetapi itu masih bisa terjadi, dan jika itu terjadi, maka ini adalah skenario terburuk, karena menggabungkan beberapa masalah yang dibahas sebelumnya. Sebenarnya, saya menemukan yang serupa di salah satu proyek pertama dari karir profesional saya.


Ketika saya bergabung dengan proyek, saya diberitahu bahwa sistem perusahaan sepenuhnya ditulis ulang dan pekerjaan proyek baru dimulai, 2 bulan yang lalu. Bayangkan betapa terkejutnya saya ketika saya melihat aplikasi web yang kompleks dengan modul administrasi yang lengkap, sudah menerapkan fungsi bisnis yang kompleks dan kerangka kerja yang dikembangkan untuk menulis modul lain. Segera saya menemukan bahwa sebagian besar dari semua ini tidak ditulis oleh tim saya: agar tidak memulai dari awal, diputuskan untuk menggunakan kembali kerangka kerja yang dikembangkan oleh perusahaan lain dalam grup kami. Masalahnya adalah bahwa kerangka kerja ini tidak terisolasi dari proyek yang dikembangkannya. Jadi tim kami hanya menerima arsip dengan semua kode sumber untuk proyek perusahaan lain, termasuk logika bisnis mereka, yang tidak ada hubungannya dengan bisnis kami sendiri. Untuk memperburuk keadaan, kami juga mewarisi dari mereka skema database dan data itu sendiri ...


Tidak mudah bagi pendatang baru di tim untuk memahami kode mana yang terkait dengan kerangka kerja, yang merujuk pada proyek kami, dan yang merujuk pada bisnis perusahaan lain. Tim ingin menghapus kekacauan ini, tetapi beberapa upaya untuk melakukan ini berakhir dengan kesalahan regresi serius karena ketergantungan antara bagian-bagian kode (bahasa tidak berubah untuk menyebutnya modul, karena hanya ada satu modul!), Dan, tentu saja, tidak ada tes otomatis di sana adalah. Selain itu, kami harus meninggalkan ide menggunakan server aplikasi yang berbeda, karena memiliki kode khusus yang digunakan oleh perusahaan lain di seluruh sistem, dan ini membuat migrasi seperti itu terlalu mahal untuk tim kecil kami.


Pada titik tertentu, kami ingin menambahkan beberapa fitur bagus ke kerangka kerja, tetapi kami diberitahu bahwa ini sudah dilakukan di perusahaan lain. Jadi kami diminta untuk menggabungkan versi kami saat ini dengan versi saat ini dari kode perusahaan lain ... Tim berhasil menghindari mimpi buruk ini dengan hanya mengarahkan (cherry-pick) beberapa komitmen yang terkait dengan fungsi baru, tetapi masih terlalu rumit dan rumit dibandingkan dengan itu apa yang kami butuhkan ...


Kami berhasil menyelesaikan proyek ini, tetapi kualitasnya sangat menyebalkan. Setidaknya 40% dari kode dan isi database adalah pemberat yang tidak digunakan, dan menghapus kode mati ini bukanlah prioritas. Saya berharap tim akhirnya memiliki kesempatan untuk memisahkan kode mereka sendiri - Saya tidak tahu, saya meninggalkan tim sebelum ini terjadi!


Semua logika bisnis Anda disimpan di dalam sistem manajemen aturan


Menempatkan beberapa logika bisnis Anda ke dalam sistem manajemen aturan adalah praktik umum. Ini, misalnya, berguna jika beberapa aturan bisnis Anda perlu sering diperbarui, dan proses pengiriman aplikasi monolitik Anda memerlukan fase pengujian yang panjang sebelum Anda dapat memverifikasi kandidat rilis, dan ini membuat tidak mungkin untuk mengkonfigurasi beberapa "volatile" Anda. "Aturan. Meskipun saya lebih suka pendekatan di mana semua aturan area subjek berada dalam kode sumber, saya dapat memahami bahwa dalam beberapa situasi sistem manajemen aturan dapat berguna.


Namun, saya menemukan sebuah aplikasi di mana hampir SEMUA logika bisnis berada dalam sistem manajemen aturan, dan kadang-kadang aturan dibuat berdasarkan pada file Excel! Selain itu, aturan tidak seharusnya diubah sangat sering, karena proyek pada dasarnya paket ETL sederhana. Proyek Java, yang mendasari semua ini, hanya terdiri dari rincian teknis tentang kerangka pemrosesan batch dan read-write murni dari sumber dan sistem target, tanpa ada koneksi dengan bidang subjek.


Akibatnya, semua aturan ditulis dalam bahasa khusus yang tidak ada yang benar-benar tahu dengan baik di tim, yang sulit untuk ditulis (IDE kami tidak mendukungnya) dan yang praktis tidak mungkin untuk di-debug dan diuji. Ketika aturan baru atau perubahan ke yang sudah ada diminta, sebagian besar pengembang dalam tim hanya menyalin aturan yang ada, yang mengarah ke file yang benar-benar identik, dengan pengecualian satu perubahan spesifik (seringkali satu-satunya perubahan tersebut adalah bidang di mana aturan itu diterapkan).


Jika ini sudah tampak seperti masalah, maka ada hal lain: sama sekali tidak ada petunjuk tentang tujuannya dalam aturan apa pun. Aturan dinamai seperti Rule1, Rule2, dan seterusnya, dengan total lebih dari 100! Dan pada dasarnya, setiap aturan terdiri dari pemeriksaan dan penugasan nilai kode keras tanpa persyaratan domain. Bahkan nama proyek tidak menjelaskan tujuan keseluruhan ETL secara keseluruhan.


Kesimpulan


Seperti yang Paman Bob jelaskan dalam bukunya "Arsitektur Bersih," ketika berpikir tentang arsitektur proyeknya, beberapa keputusan harus ditunda sampai kita benar-benar perlu membuat pilihan, tanpanya kita tidak dapat terus menambah nilai pada produk kita (seperti memilih basis data misalnya). Keputusan lain harus dibuat sangat awal - jangan menunggu sampai semuanya menjadi buruk. Untungnya, keputusan kritis semacam ini mudah diidentifikasi karena itu adalah apa yang dapat disebut "arsitektur dengan jiwa": ketika Anda memikirkan ide-ide seperti itu, Anda tidak melihat sesuatu yang baik di dalamnya - hanya masalah yang cepat atau lambat akan kembali dan akan menghantui Anda. Sayangnya, ketika bekerja dengan proyek-proyek warisan, jenis beban ini sering terkubur dalam kode, yang membuatnya sangat mahal untuk menghilangkannya.


Tapi kita tidak perlu takut. Ya, membersihkan kekacauan yang telah menumpuk selama bertahun-tahun dan bahkan puluhan tahun bukanlah tugas yang mudah, tetapi sebagai pengembang perangkat lunak profesional, kami tidak dapat membiarkan masalah seperti itu terus membusuk dan membunuh motivasi pengembang, kepercayaan pelanggan, dan kemampuan kami untuk menguntungkan mereka, tertanam dalam produk kami.


Tentu saja, setiap jenis beban arsitektur yang saya jelaskan dapat dihilangkan dengan berbagai cara - tidak ada peluru perak untuk menyelesaikan masalah ini. Namun, saya yakin bahwa tim mana pun dapat menemukan sesuatu untuk akhirnya menyingkirkan beban ini. Jadi mari kita hadapi masalah kita bersama dan mulai membereskan semuanya!

Source: https://habr.com/ru/post/id427591/


All Articles