Awalnya saya ingin menulis komentar di artikel " Saya menderita arsitektur yang buruk di C # selama sepuluh tahun ... ", tetapi saya menyadari dua hal:
- Terlalu banyak pemikiran untuk dibagikan.
- Untuk volume seperti itu, format komentarnya tidak nyaman untuk ditulis atau dibaca.
- Saya sudah lama membaca Habr, kadang saya berkomentar, tapi saya tidak pernah menulis artikel.
- Saya tidak pandai dalam daftar bernomor.
Penafian: Saya tidak mengkritik @ pnovikov atau idenya secara umum. Teksnya berkualitas tinggi (saya merasa seperti editor berpengalaman), saya membagikan beberapa pemikiran saya. Ada banyak arsitektur, tapi tidak apa-apa (ya, kedengarannya seperti judul film Korea).
Namun, mari kita lanjutkan. Pertama, opini saya tentang apa yang mempengaruhi arsitektur, kemudian tentang poin-poin kontroversial dalam artikel tentang "memperbaiki arsitektur". Saya juga akan memberi tahu Anda apa yang berhasil bagi kami - mungkin ini akan berguna bagi seseorang.
Dan tentu saja semua yang dikatakan di sini adalah pendapat pribadi berdasarkan pengalaman dan bias kognitif saya.
Tentang pendapat saya
Saya sering membuat keputusan arsitektur. Sekali besar, sekali kecil. Kadang-kadang saya membuat arsitektur dari awal. Nah, seolah-olah dari awal - pasti semuanya telah ditemukan sebelum kita, tetapi kita tidak tahu tentang sesuatu, jadi kita harus menemukan. Dan bukan karena cinta untuk membuat sepeda (katakanlah, tidak hanya karena suka), tetapi karena untuk beberapa tugas tidak ada solusi siap pakai yang sesuai dengan semua parameter.
Mengapa saya percaya bahwa arsitektur yang sama sekali berbeda berhak untuk ada? Orang mungkin berspekulasi bahwa pemrograman adalah seni, bukan kerajinan, tetapi saya tidak akan melakukannya. Pendapat saya: sekali seni, sekali kerajinan. Bukan tentang itu. Yang utama adalah tugasnya berbeda. Dan orang-orang. Untuk memperjelas, tugas adalah persyaratan bisnis.
Jika suatu hari tugas saya menjadi sama, saya akan menulis atau meminta seseorang untuk menulis jaringan saraf (atau mungkin skrip sudah cukup) yang akan menggantikan saya. Dan saya sendiri akan melakukan sesuatu yang tidak terlalu suram. Sampai saya dan, saya harap, kiamat pribadi Anda belum datang, mari kita pikirkan bagaimana tugas dan kondisi lain memengaruhi variasi arsitektur. TL&DR; - bervariasi .
Performa versus skalabilitas
Ini mungkin alasan paling tepat untuk mengubah arsitektur. Kecuali, tentu saja, lebih mudah untuk menyesuaikan arsitektur lama dengan persyaratan baru. Tetapi di sini sulit untuk secara singkat menceritakan sesuatu yang bermanfaat.
Pengaturan waktu
Katakanlah istilah (saya memastikan dua kali bahwa saya menulis dengan "o") sangat ketat. Maka kita tidak punya waktu untuk memilih, apalagi datang dengan arsitektur - ambil alat yang sudah dikenal dan gali. Tetapi ada perbedaannya - terkadang proyek yang rumit dapat diselesaikan tepat waktu hanya dengan menerapkan (dan, mungkin, menciptakan) sesuatu yang pada dasarnya baru. Seseorang mungkin mengatakan bahwa mengundang pelanggan ke pemandian adalah teknik lama, tetapi saya sedang berbicara tentang arsitektur sekarang ...
Ketika waktunya nyaman - sering kali berubah menjadi situasi yang paradoks - sepertinya Anda dapat menemukan sesuatu yang baru, tetapi mengapa? Benar, banyak yang berhasil menyerah pada godaan untuk mengambil proyek lain yang lebih membara dan mengurangi situasinya ke yang sebelumnya.
Dalam praktik saya, pengaturan waktu jarang mengarah pada revolusi dalam arsitektur, tetapi itu terjadi. Dan itu bagus.
Kecepatan dan kualitas pengembangan
Itu terjadi begitu - tim (atau seseorang dari manajemen) memperhatikan bahwa kecepatan pengembangan telah melambat, atau banyak bug telah melewati iterasi. Seringkali "arsitektur yang salah" disalahkan untuk ini. Terkadang - memang pantas. Lebih sering - sama seperti tertuduh yang paling nyaman (terutama jika tim tersebut tidak memiliki "orang tua").
Pada prinsipnya, dalam beberapa kasus semuanya tergantung pada faktor waktu. Dan di orang lain - untuk pemeliharaan, tentang itu nanti.
Pemeliharaan
Topik yang ambigu. Karena semuanya sangat subjektif dan sangat bergantung pada apa. Misalnya - dari tim, bahasa pemrograman, proses di perusahaan, jumlah adaptasi untuk klien yang berbeda. Mari kita bicara tentang faktor terakhir, menurut saya yang paling menarik.
Sekarang Anda telah membuat proyek khusus. Berhasil, tepat waktu dan sesuai anggaran, pelanggan puas dengan segalanya. Saya punya ini juga. Sekarang Anda melihat apa yang Anda gunakan dan pikirkan - jadi ini dia - tambang emas! Kami sekarang menggunakan semua perkembangan ini, kami akan segera membuat satu produk B2B, dan ... Awalnya semuanya baik-baik saja. Produk dibuat, dijual beberapa kali. Mempekerjakan lebih banyak vendor dan pengembang ("dibutuhkan lebih banyak emas"). Pelanggan puas, mereka membayar dukungan, penjualan baru terjadi ...
Dan kemudian salah satu pelanggan berkata dengan suara manusia - "Saya akan melakukan hal ini dengan cara yang sama sekali berbeda - berapa biayanya?" Nah, coba pikirkan - tempelkan beberapa if'chiks dengan kode yang berbeda (katakanlah, tidak ada waktu untuk mengacaukan DI), hal buruk apa yang bisa terjadi?
Dan pertama kali, tidak ada hal buruk yang akan terjadi. Saya bahkan tidak akan menyarankan dalam situasi seperti itu untuk memagari sesuatu yang istimewa. Rumitnya arsitektur sebelum waktunya mirip dengan pengoptimalan prematur. Namun ketika terjadi untuk kedua dan ketiga kalinya, inilah alasan untuk mengingat hal-hal seperti DI, pola "strategi", Fitur Toggle dan lain-lain yang sejenis. Dan, untuk sementara, itu akan membantu.
Dan kemudian tiba saatnya ketika Anda melihat pengaturan proyek (hanya beberapa ratus opsi) untuk bangku tes tertentu ... Ingat bagaimana menghitung jumlah kombinasi dan pikirkan - bagaimana, ibu Anda, dapatkah ini diuji? Jelas bahwa dalam dunia yang ideal ini sederhana - bagaimanapun, setiap fitur dirancang dan diimplementasikan sedemikian rupa sehingga tidak mempengaruhi yang lain dengan cara apa pun, dan jika ya, maka semua ini disediakan dan, secara umum, pengembang kami tidak pernah membuat kesalahan.
Tentu saja, saya mempertebal warnanya - Anda dapat menyoroti beberapa rangkaian fitur yang digunakan oleh pelanggan nyata, menulis lebih banyak tes (bagaimana dan mana yang menjadi topik untuk percakapan lain) dan sedikit menyederhanakan tugas. Tapi pikirkanlah - setiap rilis utama perlu diuji untuk semua pelanggan. Izinkan saya mengingatkan Anda bahwa ini bukan B2C, di mana Anda dapat mengatakan "meluncurkan fitur untuk 5% pengguna dan mengumpulkan umpan balik" - untuk B2B, Anda dapat mulai mengumpulkan umpan balik dari pengadilan ...
Solusi? Misalnya, bagi produk menjadi beberapa modul dengan siklus hidup terpisah (jangan lupa untuk menguji interaksinya). Hal ini akan mengurangi kerumitan pemeliharaan, meskipun akan mempersulit pembangunan. Dan sekarang saya tidak sedang berbicara tentang topik subur untuk holivar “monolit vs. microservices "- dalam monolit, Anda juga dapat mengatur yang serupa (meskipun lebih rumit, menurut saya).
Dan, ingat, dari sudut pandang pragmatis, di setiap tahap, kami memiliki arsitektur yang bagus.
Dan untuk apa semua ini?
Saya tidak ingin membuat Anda (dan saya sendiri) bosan dengan mencantumkan alasan lain untuk perubahan arsitektur. Sekarang mari kita sepakati bahwa arsitektur cenderung berubah seiring waktu, bergantung pada banyak faktor. Artinya: arsitektur ideal yang memecahkan "dengan baik, semua masalah" tidak ada.
Jika saya belum meyakinkan Anda tentang hal ini, lihat berbagai bahasa pemrograman dan kerangka kerja (hanya saja tidak di frontend - jangan buka topik ini). Jika seseorang mengatakan bahwa ini buruk, saya sarankan untuk melakukan eksperimen pikiran - bayangkan sebuah dunia di mana terdapat satu bahasa pemrograman tertentu. Dengan satu syarat penting - Anda tidak menyukainya. Misalnya, karena Anda tidak pernah menggunakannya, dan Anda tidak pernah bermaksud demikian.
Dan, saya akui, ada alasan bagus lainnya - datang dengan sesuatu yang baru, mengoptimalkan beberapa parameter, bermain-main dengan kompromi - sungguh menyenangkan. Sekarang kita semua (benar?) Setuju bahwa keragaman dalam arsitektur tidak masalah ...
Diskusi artikel tentang "memperbaiki arsitektur"
Bagaimana dengan IoC?
Tentang IoC Saya setuju bahwa footcloth memiliki tempat di ketentaraan, dan modul adalah barang universal. Tapi inilah sisanya ...
Jika, tentu saja, Anda mendengarkan beberapa pembela untuk "kode bersih", maka Anda dapat membuat kode untuk gunung layanan, yang masing-masing akan memiliki rata-rata satu setengah metode, dan dalam metode - dua setengah baris. Tapi kenapa? Sejujurnya, Anda pasti ingin mengikuti prinsip-prinsip yang akan membantu Anda mengatasi masalah yang tidak mungkin terjadi di masa mendatang, tetapi bahkan mencoreng logika sederhana di lusinan file? Atau apakah cukup bagi Anda untuk menulis kode yang berfungsi dengan baik sekarang?
Ngomong-ngomong, sekarang saya sedang mengerjakan modul yang pasti akan digunakan di berbagai produk dan, kemungkinan besar, akan secara aktif "menyetel". Jadi di sana saya berusaha untuk tidak "dangkal". Tidak terbayar. Meskipun di dalamnya saya hanya menggunakan implementasi antarmuka lebih sering dari biasanya.
Jadi, jika kita memiliki modul dan kita tidak "kecil", lalu dari mana datangnya masalah performa IoC atau "footcloth konfigurasi IoC" yang tidak didukung? Saya belum menemukan.
Namun, saya akan mengklarifikasi kondisi kerja kami:
- Modul kami bukanlah yang "disediakan oleh hampir semua kerangka kerja IoC", tetapi "modul langsung" - yang berkomunikasi satu sama lain dari jarak jauh melalui API (terkadang, karena alasan kinerja, Anda dapat menempatkannya dalam satu proses, tetapi skema kerja tidak akan berubah).
- IoC digunakan sesederhana mungkin dan sesederhana mungkin - dependensi dimasukkan ke dalam parameter konstruktor.
- Ya, kami sekarang memiliki arsitektur layanan mikro, tetapi di sini kami mencoba untuk tidak terlalu kecil.
Tip: antarmuka dapat disimpan dalam file yang sama dengan kelas - akan lebih mudah (jika, tentu saja, Anda menggunakan IDE biasa, dan bukan notepad). Saya membuat pengecualian ketika antarmuka (atau komentar untuk mereka) tumbuh. Tapi ini semua rasa, tentu saja.
Apa yang salah dengan ORM dan mengapa akses database langsung?
Ya, saya sendiri akan mengatakan apa yang salah - banyak dari mereka terlalu jauh dari SQL. Tapi tidak semua. Oleh karena itu, alih-alih "bertahan sementara O / RM menghapus 3.000 objek" atau menghasilkan yang lain, temukan satu yang cocok untuk Anda.
Tip: coba LINQ ke DB . Ini seimbang, ada metode Perbarui / Hapus untuk beberapa baris. Berhati-hatilah - membuat ketagihan. Ya, tidak ada fitur EF dan konsep yang sedikit berbeda, tetapi saya lebih menyukai EF.
Ngomong-ngomong, bagus sekali ini adalah pengembangan dari rekan senegara kita. Igor Tkachev - rasa hormat (saya tidak menemukannya di Habré).
UPD: RouRdicatat di komentar bahwa ada ekstensi untuk EF Core yang memungkinkan operasi massal. Saya tidak akan menyerahkan LINQ kepada DB, karena itu bagus .
Apa yang salah dengan tes database?
Ya, mereka akan lebih lambat dari data di memori. Apakah itu fatal? Tidak, tentu saja tidak. Bagaimana cara mengatasi masalah ini? Berikut dua resep yang paling baik digunakan pada saat bersamaan.
Resep nomor 1. Anda mengambil seorang pengembang keren yang suka melakukan segala macam hal keren dan berdiskusi dengannya bagaimana mengatasi masalah ini dengan indah. Saya beruntung karenamemaksamemecahkan masalah lebih cepat dari yang terlihat (saya bahkan tidak ingat apakah kita membahasnya atau tidak). Bagaimana? Dibuat (dalam sehari, tampaknya) pabrik uji untuk ORM, yang menggantikan subset operasi utama dengan mengakses array.
Sempurna untuk pengujian unit sederhana. Pilihan alternatifnya adalah dengan menggunakan SQLite atau yang serupa daripada database "besar".
Komentar oleh memaksa: . -, , ORM, , SQL . -, , , , , .. . .
Resep nomor 2. Saya lebih suka menguji skenario bisnis pada database nyata. Dan jika proyek menyatakan kemampuan untuk mendukung beberapa DBMS, pengujian dilakukan untuk beberapa DBMS. Mengapa? Itu mudah. Dalam pernyataan "Saya tidak ingin menguji server database", sayangnya, ada substitusi konsep. Saya, Anda tahu, tidak menguji apakah penggabungan berhasil atau dipesan oleh.
Saya menguji kode saya bekerja dengan DB. Dan mengetahui bahwa versi berbeda dari DBMS yang sama dapat menghasilkan hasil yang berbeda pada kueri yang sama ( bukti ), saya ingin memeriksa skenario utama persis pada database yang akan digunakan kode ini.
Biasanya tes seperti itu bagi saya terlihat seperti ini:
- Untuk sekelompok tes (Fixture), itu dihasilkan dari awal menggunakan metadata database. Jika perlu, buku referensi yang diperlukan diisi.
- Setiap skrip menambahkan data yang diperlukan sendiri selama bagian tersebut (pengguna juga melakukannya). Tidak begitu dalam uji kinerja, tapi itu cerita yang sama sekali berbeda ...
- Setelah setiap pengujian, kelebihan data (kecuali untuk buku referensi) dihapus.
Saran: jika pengujian semacam itu dilakukan untuk Anda secara obyektif untuk waktu yang lama (dan bukan karena sudah waktunya untuk mengoptimalkan kueri ke database), buatlah build yang akan lebih jarang menjalankannya (kategori pengujian atau proyek terpisah untuk membantu). Jika tidak, pengembang tidak akan ingin menjalankan sisanya sendiri - tes cepat.
Transaksi dan email
Saya hanya akan menambahkan cerita "transaksi di database karena suatu alasan jatuh, dan e-mail hilang." Dan betapa menyenangkannya ketika sebuah transaksi menunggu server email yang tidak tersedia, mempertaruhkan seluruh sistem karena beberapa pemberitahuan yang kemudian dikirim pengguna ke keranjang tanpa membaca ...
Benar, saya selalu percaya bahwa hanya bulan Juni
Hasil
Secara umum, jika @ pnovikov tidak memiliki rencana untuk menaklukkan dunia dengan bantuan satu-satunya
Saya hampir tidak akan menggunakan kerangka yang diusulkan. Alasannya sederhana - kami sudah memiliki arsitektur yang ideal ...
NB Jika Anda memiliki keinginan untuk membahas sesuatu di komentar, saya akan dengan senang hati mengambil bagian di dalamnya.