Selama beberapa tahun terakhir, kami perlahan-lahan beralih ke kode tulisan yang semakin baik, beberapa langkah sekaligus. Kami akhirnya mulai beralih ke sesuatu yang setidaknya menyerupai SOLID, tapi kami belum cukup di sana. Sejak beralih, salah satu keluhan terbesar dari pengembang adalah bahwa mereka tidak tahan meninjau rekan dan melintasi lusinan file di mana sebelumnya setiap tugas hanya mengharuskan pengembang menyentuh 5-10 file.
Sebelum mulai beralih, arsitektur kami diatur seperti halnya (diberikan, dengan satu atau dua urutan file lebih besar):
Solution
- Business
-- AccountLogic
-- DocumentLogic
-- UsersLogic
- Entities (Database entities)
- Models (Domain Models)
- Repositories
-- AccountRepo
-- DocumentRepo
-- UserRepo
- ViewModels
-- AccountViewModel
-- DocumentViewModel
-- UserViewModel
- UI
Dari segi file, semuanya sangat linier dan kompak. Jelas ada banyak duplikasi kode, kopling ketat, dan sakit kepala, namun, semua orang bisa melewatinya dan mencari tahu. Pemula yang lengkap, orang yang belum pernah membuka Visual Studio, dapat mengetahuinya hanya dalam beberapa minggu. Kurangnya keseluruhan kompleksitas file membuatnya relatif mudah bagi pengembang pemula dan karyawan baru untuk mulai berkontribusi tanpa terlalu banyak waktu. Tapi ini cukup banyak di mana manfaat dari gaya kode keluar jendela.
Saya dengan sepenuh hati mendukung setiap upaya yang kami lakukan untuk memperbaiki basis kode kami, tetapi sangat umum untuk mendapatkan balasan dari anggota tim lainnya tentang perubahan paradigma besar-besaran seperti ini. Beberapa poin pelekatan terbesar saat ini adalah:
- Tes Unit
- Hitungan Kelas
- Kompleksitas Peer Review
Unit test telah menjadi penjualan yang sangat sulit bagi tim karena mereka semua percaya mereka membuang-buang waktu dan bahwa mereka dapat menangani-menguji kode mereka lebih cepat secara keseluruhan daripada masing-masing bagian secara individual. Menggunakan tes unit sebagai dukungan untuk SOLID sebagian besar sia-sia dan sebagian besar menjadi lelucon pada saat ini.
Hitungan kelas mungkin merupakan rintangan tunggal terbesar untuk diatasi. Tugas yang digunakan untuk mengambil 5-10 file sekarang dapat mengambil 70-100! Meskipun masing-masing file ini memiliki tujuan yang berbeda, volume file yang banyak dapat sangat besar. Respons dari tim sebagian besar adalah keluhan dan garukan kepala. Sebelumnya sebuah tugas mungkin memerlukan satu atau dua repositori, satu atau dua model, lapisan logika, dan metode pengontrol.
Sekarang, untuk membangun aplikasi penyimpanan file sederhana, Anda memiliki kelas untuk memeriksa apakah file tersebut sudah ada, kelas untuk menulis metadata, kelas untuk abstrak DateTime.Now
sehingga Anda dapat menyuntikkan waktu untuk pengujian unit, antarmuka untuk setiap file yang berisi logika, file mengandung tes unit untuk setiap kelas di luar sana, dan satu atau lebih file untuk menambahkan semuanya ke wadah DI Anda.
Untuk aplikasi ukuran kecil hingga menengah, SOLID adalah penjualan yang sangat mudah. Semua orang melihat manfaat dan kemudahan perawatan. Namun, mereka tidak melihat proposisi nilai yang baik untuk SOLID pada aplikasi skala sangat besar. Jadi saya mencoba mencari cara untuk meningkatkan organisasi dan manajemen agar kita dapat melewati rasa sakit yang terus tumbuh.
Saya pikir saya akan memberikan sedikit lebih kuat dari contoh volume file berdasarkan pada tugas yang baru saja selesai. Saya diberi tugas untuk mengimplementasikan beberapa fungsi di salah satu layanan microser kami yang lebih baru untuk menerima permintaan sinkronisasi file. Ketika permintaan diterima, layanan melakukan serangkaian pencarian dan pemeriksaan, dan akhirnya menyimpan dokumen ke drive jaringan, serta 2 tabel database terpisah.
Untuk menyimpan dokumen ke drive jaringan, saya memerlukan beberapa kelas khusus:
- IBasePathProvider
-- string GetBasePath() // returns the network path to store files
-- string GetPatientFolderName() // gets the name of the folder where patient files are stored
- BasePathProvider // provides an implementation of IBasePathProvider
- BasePathProviderTests // ensures we're getting what we expect
- IUniqueFilenameProvider
-- string GetFilename(string path, string fileType);
- UniqueFilenameProvider // performs some filesystem lookups to get a unique filename
- UniqueFilenameProviderTests
- INewGuidProvider // allows me to inject guids to simulate collisions during unit tests
-- Guid NewGuid()
- NewGuidProvider
- NewGuidProviderTests
- IFileExtensionCombiner // requests may come in a variety of ways, need to ensure extensions are properly appended.
- FileExtensionCombiner
- FileExtensionCombinerTests
- IPatientFileWriter
-- Task SaveFileAsync(string path, byte[] file, string fileType)
-- Task SaveFileAsync(FilePushRequest request)
- PatientFileWriter
- PatientFileWriterTests
Jadi itu total 15 kelas (tidak termasuk POCO dan perancah) untuk melakukan penghematan yang cukup mudah. Jumlah ini menggelembung secara signifikan ketika saya perlu membuat POCO untuk mewakili entitas dalam beberapa sistem, membangun beberapa repo untuk berkomunikasi dengan sistem pihak ketiga yang tidak sesuai dengan ORM kami yang lain, dan membangun metode logika untuk menangani seluk-beluk operasi tertentu.