Pesawat luar angkasa pada mesin pembakaran internal. Bertahanlah dari pertempuran dengan hutang teknis



Bagaimana cara bertahan dalam pertempuran dengan hutang teknis? Apa yang harus dilakukan jika Anda memiliki warisan tahap parah? Dalam artikel tersebut, dengan menggunakan contoh tiga kasus, saya mengusulkan untuk mencari cara bagaimana membangun proses bekerja dengan hutang teknis dan pendekatan teknik mana yang digunakan untuk ini.

Nama saya Denis, saya Pemimpin Tim Backend di Wrike. Saya bertanggung jawab untuk pengiriman di tim saya dan untuk pertumbuhan pengembang di beberapa tim. Kebetulan hampir semua pengalaman saya bekerja di fintech. Saya telah bekerja untuk dua bank besar, dan sekarang saya bekerja di Wrike.

Di bank, Anda belajar bekerja dengan sistem di mana keandalan dan toleransi kesalahan penting. Dan ada banyak Legacy di sana, dan saya mengalami semua ini sebagai pengembang dan membantu orang lain untuk mengalami diri saya sebagai tim pemimpin.

Wrike adalah solusi kolaborasi tim SaaS yang kami jual kepada pelanggan kami. Kami membuat Wrike menggunakan Wrike untuk mengatur pengembangan.

Salah mengembangkan tim scrum tiga puluh. Layanan ini tersedia 24/7, sehingga keputusan yang kami buat harus dapat diandalkan. Jika terjadi kesalahan, maka ini akan mempengaruhi pekerjaan hampir semua tim.

Mengapa kapal luar angkasa?


Starship adalah metafora yang saya gunakan untuk menggambarkan apa yang sedang kita kerjakan dengan programmer. Aplikasi dimulai dengan beberapa modul. Kemudian mulai tumbuh: beban besar datang padanya, layanan microser muncul, komunikasi di antara mereka, integrasi, API eksternal, klien. Ternyata ekosistem yang besar dan terhubung. Semakin besar dan semakin lama aplikasinya, ekosistem semakin terhubung. Dan yang lebih penting adalah untuk menjaga agar node yang signifikan tetap up-to-date dan dalam kondisi yang dapat diandalkan. Menjadi sangat sedih ketika yang terpenting dari mereka tidak memenuhi persyaratan hari ini, atau gagal.
Kapal luar angkasa Anda tidak akan melompat ke warp jika bekerja pada AI-95. Sistem tidak akan menavigasi melalui empat galaksi jika komputer pusat adalah Intel Celeron.

Apa itu utang teknis?


Bayangkan Anda memiliki fitur di mana bug terus muncul. Seorang penguji mendatangi Anda dan berkata, "Minggu ini kami menemukan empat bug baru di sana." Apakah ini utang teknis atau tidak? Dan jika kehadiran fitur ini menghalangi cerita lain yang perlu dilakukan? Dan jika itu hanya sulit untuk bekerja dengan solusinya, dan Anda selalu menyebutnya ulang? Jika pengguna mengeluh tentang fitur? Dan jika dia tidak memenuhi persyaratan yang dikenakan padanya hari ini, atau menyinggung perasaan pengembang yang berusaha untuk keunggulan?

Dalam artikel ini, dengan hutang teknis saya akan memahami fitur-fitur, solusi atau pendekatan yang mengganggu pengembangan produk lebih lanjut. Semua masalah yang dijelaskan di atas adalah hasil dari hutang teknis. Ini adalah alasan spesifik: mengapa dia dan mengapa Anda perlu bekerja dengannya.

Algoritma Hutang Teknis


Untuk bekerja secara efektif dengan hutang teknis, Anda perlu mengajukan tiga pertanyaan dasar.

  1. Untuk apa? Mengapa kita berjanji untuk melakukan sesuatu dengannya? Mengapa kita membutuhkan pekerjaan ini? Mengapa menghabiskan uang perusahaan, jam pengembangan, waktu insinyur? Harus ada pemahaman yang jelas tentang manfaat apa yang akan kita dapatkan dengan menyelesaikan masalah tertentu. Dari definisi itu jelas bahwa utang teknis menghambat pengembangan produk. Bekerja dengannya, kita akan mendapatkan fitur dan kemampuan baru.
  2. Apa? Kita harus memahami dengan jelas di mana utang teknis dimulai, di mana ia berakhir, bagaimana kelihatannya, dan berapa banyak pekerjaan yang harus dilakukan untuk menghilangkannya.
  3. Bagaimana? Tindakan yang perlu dilakukan dengan utang teknis untuk menyingkirkannya.

Untuk menjawab pertanyaan terakhir, ada empat langkah algoritma iteratif sederhana. Langkah pertama adalah menyoroti utang teknis dan memahami batasannya. Langkah selanjutnya adalah memisahkannya dari yang lainnya: enkapsulasi, masukkan kontrak kerja antara solusi yang telah Anda alokasikan, dan sisanya dari sistem. Setelah itu, Anda dapat membuat solusi baru di dekatnya, menggantinya, dan, dengan demikian, bagian dari hutang teknis akan meninggalkan aplikasi. Mengulangi iterasi ini beberapa kali, Anda akan mendapatkan solusi yang sudah jadi.



Sekarang mari kita lihat bagaimana algoritma bekerja pada kenyataannya menggunakan beberapa case sebagai contoh.

Kasus pertama


Ada aplikasi yang bekerja dengan pesanan dari pelanggan - sistem manajemen pesanan. Aplikasi ini ditulis sejak lama, pada tahun 2010, dan dibangun di atas teknologi terbaru saat itu. Aplikasi ini telah berhasil beroperasi dalam produksi selama 9 tahun terakhir, tetapi hari ini bisnis memahami bahwa perlu untuk menangkap pasar baru dan mengembangkan sistem lebih lanjut. Pada saat yang sama, penting untuk menyimpan data dan meningkatkan fungsionalitas baru dalam sistem.



Ternyata ada teknologi yang sudah lama mati, tetapi ada juga data yang tidak bisa hilang. Tidak semua fitur dapat diimplementasikan dalam aplikasi menggunakan teknologi lama. Karena itu, situasinya, sejujurnya, terlihat seperti ini:



Masalahnya di sini bukan pada kerangka kerja lama, tetapi dalam situasi yang kita miliki: aplikasi tidak didukung, hampir mustahil untuk menemukan pengembang untuk kerangka kerja satu dekade yang lalu. Kita harus melakukan sesuatu.

Mari kita jalankan algoritma. Beberapa bagian dari hutang teknis dapat dibedakan dan secara iteratif mendekati proses ini. Pertama, mari kita berurusan dengan Frontend. Kita bisa meluncurkan Frontend baru menggunakan Backend lama. Kami akan dapat memperluas Frontend baru, menyesuaikannya dengan teknologi modern, itu akan memenuhi tujuan kami. Kita bisa mengandalkan sepenuhnya pada Backend yang lama, atau harus sedikit dimodifikasi untuk bekerja dengan Frontend yang baru. Langkah selanjutnya adalah enkapsulasi. Dengan enkapsulasi, arsitektur membantu kita di sini. Titik enkapsulasi dalam kasus ini akan menjadi kontrak dengan Backend. Setelah kami meluncurkan Frontend baru, kami dapat menghapus bagian Frontend yang lama. Sekarang seluruh aplikasi kita akan menjadi lebih hijau dan lebih hijau.



Langkah selanjutnya adalah bekerja dengan Backend. Di sini, titik enkapsulasi sudah akan menjadi lapisan basis data. Ternyata arsitektur akan kembali melakukan enkapsulasi ini untuk kita. Dan kita dapat membuat solusi baru di dekatnya, bekerja dengan data yang sama, dan mentransfer Frontend ke sana. Sekarang kami telah sepenuhnya meninggalkan solusi lama dan dapat membuangnya. Ini memungkinkan kami untuk mencapai tujuan yang kami tetapkan untuk proyek ini.



Kasus kedua


Ambil kasing lebih rumit. Ada aplikasi, ia memiliki fitur khusus yang bertanggung jawab untuk menyimpan pasangan mata uang dalam database. Misalnya, rubel dolar, dolar yen, dan sebagainya. Informasi disimpan dalam database dalam sebuah tabel. Dan untuk membuatnya sedikit lebih menyenangkan, tambahkan beberapa dependensi: ada konsumen yang menerima data langsung dari basis data, dan penyedia data yang dapat menyediakannya, sekali lagi, langsung ke basis data.



Kami tidak puas dengan format data dan cara data ini masuk ke dalam basis data. Tetapi Anda harus memperbaikinya dengan hati-hati, ada banyak ketergantungan.

Untuk melakukan ini, pilih bagian - data tertentu. Anda perlu merangkum mereka. Untuk melakukan ini, masukkan interlayer. Tugas mereka adalah memastikan bahwa konsumen dan pemasok tidak melihat adanya perubahan. Inilah arti enkapsulasi. Sekarang kita dapat mengubah struktur penyimpanan, karena ini tidak akan mempengaruhi dependensi eksternal. Setelah itu kita bisa membangun solusi baru yang merekam data dalam format baru. Dan langkah terakhir adalah mentransfer data lama ke format baru dan mendapatkan apa yang kita inginkan dari proyek kami: data dalam format baru, dan logika lama dapat dihapus dari aplikasi.


Dalam proses ini, konsumen data tidak akan melihat perubahan, yang berarti kami melakukannya sepenuhnya dengan aman, sambil mempertahankan kompatibilitas ke belakang. Kemudian, jika perlu untuk proyek tersebut, Anda dapat bekerja dengan konsumen dan penyedia data sehingga mereka juga menggunakan format baru.

Kasus ketiga


Untuk meningkatkan skala dan memahami cara kerjanya dalam proyek-proyek besar, bayangkan ada proyek besar, basis kode besar dan beberapa jenis fungsi kunci yang benar-benar tumbuh di semua titik aplikasi. Bagian lain dari Backend menggunakannya, ia memiliki akses ke API Publik, yaitu, data bocor ke suatu tempat. Fitur ini digunakan di Frontend, dalam sistem eksternal, dan bahkan dalam lampiran langsung dari database ke analytics. Untuk menjadikan contoh lebih menyenangkan, tambahkan sejumput Legacy di sini. Yah, sedikit.



Dua fakta warisan yang menyenangkan:

  1. Ini pasti berhasil.
  2. Tidak ada yang tahu cara kerjanya. Itu sebabnya Legacy.

Ketika bekerja dengan kasus seperti itu, di mana ada banyak titik kontak dan banyak hal yang tidak diketahui, perlu dipahami: dengan apa, memang, kami bekerja, seperti apa solusi ini dan seperti apa kemampuannya. Penting untuk memahami bagaimana solusi yang kami ingin ulang atau ingin menyingkirkan berinteraksi dengan sisa aplikasi. Kita perlu menemukan semua landasan bersama: untuk memahami bagaimana mereka bekerja, untuk memahami kontrak mereka agar dapat menawarkan sesuatu yang lain.

Ada beberapa pendekatan di sini yang dapat membantu, terutama jika skala bencana cukup besar dalam jumlah kode:

  • . Java , , , . , , , , ;
  • . , , , . , , . , ;
  • -.

Jika kami menemukan kesamaan dalam kode, Anda dapat menggunakannya dan membungkus solusi dengan titik enkapsulasi. Kami memperkenalkan kontrak baru untuk interaksi aplikasi dengan fitur kami.



Di sini jumlah warisan berkurang, karena pada saat ini kita sudah mulai memasukkan apa yang kita inginkan ke dalam aplikasi.

Selanjutnya, Anda perlu mengambil langkah pertama menuju solusi baru - tes. Mereka akan menutup fakta yang sangat lucu tentang Legacy No. 2, yang saya sebutkan sebelumnya. Tes akan menunjukkan cara kerja solusi Anda. Selain memeriksa aliran kunci, Anda perlu memastikan bahwa itu juga jatuh tepat di tempat yang Anda harapkan darinya, dan persis seperti yang Anda harapkan darinya.

Sering terjadi bahwa solusi yang dibuat sekali untuk keperluan bisnis digunakan pada 100%, dan hari ini solusi tersebut bersinggungan dengan tujuan saat ini hanya pada 30%, dan pada 70% - tidak. Dalam kenyataan hari ini, 70% ini tidak lagi penting. Tes yang Anda tulis akan menyoroti sangat 30%. Setelah menjalankan tes berlapis, Anda dapat memahami kode mana yang tidak digunakan sama sekali, menghapusnya dan mengurangi konektivitas dan kompleksitas solusi Anda.

Jika kami, setelah menulis tes dan memahami cara kerjanya, mulai memperkenalkan solusi baru di area enkapsulasi, kami akan secara bertahap menggantikan semua yang tidak kami butuhkan, menghapus warisan dan mengganti solusi dengan yang baru yang sesuai dengan kebutuhan kami.



Solusi baru harus sederhana, dapat dimengerti dan harus secara khusus menyelesaikan masalah Anda, khususnya hari ini dan untuk tujuan langsung spesifik. Tidak perlu masuk lebih dalam ke rekayasa ulang, karena kita menutup tujuan akhir hari ini.

Dan ini adalah tempat di mana Anda harus berhenti, bertahan pada saat itu dan berpikir: "Mengapa kita melakukan ini?" Pada tahap ini, Anda akan memiliki banyak informasi tentang cara solusi bekerja, apa yang ada di dalamnya dan apa yang tidak. Anda menulis tes, menandai kode, membuat diagram, dan sekarang Anda lebih memahami urutan besarnya. Mungkin ini adalah titik di mana itu layak dihentikan dan dipahami: apakah mungkin untuk memecahkan masalah yang jauh lebih besar? Dan inilah yang pernah menyelamatkan urutan kuartal pengembangan untuk proyek kami, karena kami memilih arah yang tepat untuk pengembangan proyek.

Bagaimana cara mengatur pekerjaan


Kami mengambil pendekatan di mana kami mencoba memecah solusi baru menjadi iterasi. Ini adalah bagian spesifiknya yang dapat diluncurkan dalam produksi dan yang akan mengubah sesuatu di dalamnya.

Untuk memahami apa itu iterasi dan tugas apa yang dikandungnya, kami meminjam konsep Definisi Selesai dari Scrum. Ini adalah seperangkat kriteria yang harus dipenuhi agar sebuah cerita dipertimbangkan terpenuhi.

Di sini saya menggunakan konsep ini dalam bentuk yang sedikit berbeda. Dengan Definisi Selesai, saya memahami uraian tentang apa yang akan berubah dalam aplikasi ketika iterasi tertentu masuk ke produksi.

Mari kita ingat contoh pertama dengan sistem manajemen pesanan. Di dalamnya, pengguna dapat membuat pesanan baru menggunakan UI baru dan Backend lama. Ini adalah jenis iterasi - bagian spesifik dari fungsionalitas yang dapat kita mulai dalam produksi, dan itu akan berfungsi. Atau pengguna dapat masuk dengan model hak akses baru - ini juga merupakan perubahan kualitatif. Jadi, Anda dapat menggambarkan apa yang sebenarnya diberikan setiap iterasi dalam perang salib Anda dalam perang melawan utang teknis.

Ketika Anda memecah solusi menjadi iterasi, mungkin ada banyak masalah. Akan ada ketergantungan di antara mereka, kami mendapatkan grafik keseluruhan. Di kolom ini akan ada beberapa cara untuk mencapai hasil akhir. Anda dapat menggunakan perencanaan terbalik - alat yang akan membantu mengurangi waktu kerja. Kami mulai dari titik akhir proyek dan mengajukan pertanyaan: "Apa yang perlu dilakukan untuk mencapai tujuan ini?". Kami memahami bahwa untuk mencapai tujuan ini, kami harus mengambil langkah sebelumnya. Jadi, kami bergerak dari ujung ke awal dan pada setiap langkah menengah kami menjawab pertanyaan ini, melewati jalur kritis. Setelah pendekatan seperti itu menyelamatkan kita, kuartal pembangunan.

Alat yang disebut grafik Gantt sangat cocok untuk memvisualisasikan pekerjaan. Ini adalah diagram yang menunjukkan hubungan antara tugas, durasi mereka dan bagaimana proyek terlihat secara visual. Dalam gambar adalah screenshot dari Wrike. Kami memiliki alat ini, kami secara aktif menggunakannya untuk bekerja dengan proyek.



Jika Anda bekerja pada solusi yang luas, Anda mungkin menghadapi situasi di mana seseorang mengubah kode yang Anda refactor, beradaptasi, membimbing dalam proses Anda dan yang baru saja Anda pikirkan. Perubahan ini dapat mempersulit Anda untuk berhadapan dengan hutang teknis.

Anda dapat melindungi diri dari perubahan tersebut dengan beberapa cara:

  • โ€” . , , - , .
  • , . git hook, git commit git push. unit test, , - , , , : .

Anda juga dapat mengonfigurasi sistem pemantauan eksternal untuk kode Anda. Di Wrike kami menggunakan PMD. Sistem mulai dan memeriksa kepatuhan dengan aturan tertentu setiap baris kode baru. Gambar adalah contoh dari build log. Di sini aturan "hasil metode publik harus tidak berubah" dilanggar, PMD berbicara tentang hal itu dan menunjukkan di baris mana - ini dia metode "metode yang salah". Di bawah ini adalah petunjuk apa yang perlu Anda lakukan dengannya untuk memperbaikinya. Dengan demikian, kita selalu tahu di mana aturan dilanggar dan bagaimana cara memperbaikinya.



Cara melewati bos terakhir


Satu hal penting yang belum kita bicarakan adalah bos terakhir, yang harus melewati saat bekerja dengan hutang teknis. Bisnis, pemilik produk, pelanggan - setiap orang memiliki nama yang berbeda untuk itu. Ini dapat mengganggu menyeret inisiatif rekayasa kami ke depan ke produksi.

Kita semua tahu tentang kasus ketika pemilik produk tidak mendorong solusi paling optimal dari sudut pandang teknik. Tetapi bahkan jika pemilik produk Anda menatap lembaran titanium, Anda masih bisa bernegosiasi dengan dia. Bekerja dengan hutang teknis, Anda membuka peluang baru, dan pemilik produk membutuhkan mereka untuk mengembangkan produk mereka.

Anda dapat menyetujui kuota waktu. Sebagai contoh, 10% dari waktu pengembang akan mencurahkan untuk bekerja pada hutang teknis. Kuota seperti itu tidak akan memungkinkan penghapusan utang teknis, tetapi akan memungkinkannya untuk tidak membengkak.

Jelas, sulit untuk berbicara tentang utang teknis, jika tidak jelas apa sebenarnya pembicaraan itu. Oleh karena itu, tim Anda harus memiliki jaminan teknis, di mana ada tugas yang dievaluasi dan diprioritaskan oleh pengembang.

Namun, alat di atas tidak akan memungkinkan untuk berurusan dengan proyek skala besar. Dan dalam hal ini, penting, dalam hal apa yang telah terdaftar sebelumnya (3 pertanyaan untuk hutang teknis, proyek dalam pelacak, jalur kritis dalam grafik, dll.), Untuk dapat menjelaskan manfaat proyek kepada pelanggan Anda. Dan semakin rumit cerita, semakin banyak pemahaman yang Anda sampaikan. Sebuah bisnis memiliki tujuan yang Anda bantu capai. Penting bagi Anda untuk terus mengikuti apa yang terjadi tidak hanya sekarang, tetapi juga rencana yang akan menjadi kenyataan di kuartal. Oleh karena itu, berkomunikasi dengan bisnis, memahami apa yang ingin dilakukan dan apa cara untuk mencapai tujuan ini, dan gunakan pengetahuan ini untuk menggabungkan tujuan teknik dan tujuan bisnis Anda.

Mungkin tujuannya tidak akan bersamaan, tetapi dalam seperempat atau bahkan dalam satu tahun. Tetapi ini akan membuat Anda mengerti kapan bisnis akan siap untuk perubahan.

Jika Anda berhasil menyinkronkan tujuan, Anda akan menerima semua bonus: prioritisasi, sumber daya, dan organisasi dari semua pekerjaan. Pemilik produk akan membantu Anda melakukan ini. Tugas utama adalah untuk setuju dengannya.

Total


Ketika kita berbicara tentang perubahan dalam bidang-bidang utama produk, algoritma empat langkah sederhana menjadi rumit:



Dua langkah lagi ditambahkan. Yang pertama adalah pemahaman tentang apa yang kami kerjakan. Yang kedua - setelah enkapsulasi - pemahaman tentang bagaimana solusi bekerja dan bagaimana mencegah perubahan dalam kode Anda.

Dengan menggunakan algoritma ini dan rekomendasi saya untuk mengatur proses, Anda dapat bekerja dengan utang teknis apa pun.

Artikel ini didasarkan pada pidato saya di rapat, Anda dapat melihat laporan video .

All Articles