Seorang pengembang yang baik yang bekerja dengan saya memberi tahu saya baru-baru ini tentang beberapa kesulitan yang ia miliki dalam mengimplementasikan fitur dalam beberapa kode yang kami warisi; katanya masalahnya adalah bahwa kode itu sulit untuk diikuti. Dari sana, saya melihat lebih dalam ke dalam produk dan menyadari betapa sulitnya untuk melihat jalur kode.
Ini menggunakan banyak antarmuka dan lapisan abstrak, sehingga mencoba memahami di mana segala sesuatu dimulai dan berakhir cukup sulit. Itu membuat saya berpikir tentang waktu saya melihat proyek-proyek sebelumnya (sebelum saya begitu menyadari prinsip-prinsip kode bersih) dan merasa sangat sulit untuk berkeliling dalam proyek, terutama karena alat navigasi kode saya akan selalu mendaratkan saya di sebuah antarmuka. Dibutuhkan banyak usaha ekstra untuk menemukan implementasi konkret atau di mana ada sesuatu yang ditransfer dalam beberapa arsitektur tipe plugin.
Saya tahu beberapa pengembang benar-benar menolak wadah injeksi ketergantungan karena alasan ini. Ini membingungkan jalur perangkat lunak sehingga kesulitan navigasi kode secara eksponensial meningkat.
Pertanyaan saya adalah: ketika suatu kerangka kerja atau pola memperkenalkan begitu banyak overhead seperti ini, apakah itu layak? Apakah ini merupakan gejala dari pola implementasi yang buruk?
Saya kira pengembang harus melihat ke gambaran yang lebih besar tentang apa yang dibawa oleh abstraksi ke proyek untuk membantu mereka melewati frustrasi. Namun biasanya, sulit untuk membuat mereka melihat gambaran besar itu. Saya tahu saya gagal menjual kebutuhan IOC dan DI dengan TDD. Bagi para pengembang itu, penggunaan alat-alat itu hanya terlalu mudah dibaca kode.
sumber
Yah, abstraksi tidak cukup dan kode Anda sulit dimengerti karena Anda tidak dapat mengisolasi bagian mana yang melakukan apa.
Terlalu banyak abstraksi dan Anda melihat abstraksi tetapi bukan kode itu sendiri, dan kemudian membuat sulit untuk mengikuti utas eksekusi nyata.
Untuk mencapai abstraksi yang baik, seseorang harus KISS: lihat jawaban saya untuk pertanyaan ini untuk mengetahui apa yang harus diikuti untuk menghindari masalah semacam itu .
Saya pikir menghindari hierarki dan penamaan yang mendalam adalah hal paling penting untuk dilihat pada kasus yang Anda gambarkan. Jika abstraksi diberi nama baik, Anda tidak perlu terlalu dalam, hanya ke tingkat abstraksi di mana Anda perlu memahami apa yang terjadi. Penamaan memungkinkan Anda mengidentifikasi di mana tingkat abstraksi ini.
Masalahnya muncul dalam kode tingkat rendah, ketika Anda benar-benar membutuhkan semua proses untuk dipahami. Kemudian, enkapsulasi melalui modul yang terisolasi jelas adalah satu-satunya bantuan.
sumber
Bagi saya itu masalah kopling dan terkait dengan rincian desain. Bahkan bentuk kopling yang paling longgar pun memperkenalkan ketergantungan dari satu hal ke hal lainnya. Jika itu dilakukan untuk ratusan hingga ribuan objek, bahkan jika semuanya relatif sederhana, patuhi SRP, dan bahkan jika semua dependensi mengalir menuju abstraksi yang stabil, yang menghasilkan basis kode yang sangat sulit untuk dipikirkan sebagai keseluruhan yang saling terkait.
Ada hal-hal praktis yang membantu Anda mengukur kompleksitas basis kode, tidak sering dibahas dalam SE teoritis, seperti seberapa jauh ke dalam tumpukan panggilan yang bisa Anda dapatkan sebelum Anda mencapai akhir, dan seberapa dalam Anda harus pergi sebelum Anda bisa, dengan sangat percaya diri, pahami semua kemungkinan efek samping yang dapat terjadi pada tingkat setumpuk panggilan termasuk jika terjadi pengecualian.
Dan saya telah menemukan, hanya dalam pengalaman saya, bahwa sistem yang lebih datar dengan tumpukan panggilan dangkal cenderung jauh lebih mudah untuk dipikirkan. Contoh ekstrem adalah sistem entitas-komponen di mana komponen hanyalah data mentah. Hanya sistem yang memiliki fungsionaltiy, dan dalam proses penerapan dan penggunaan ECS, saya menemukan itu sistem yang paling mudah, sejauh ini, untuk alasan ketika basis kode kompleks yang menjangkau ratusan ribu baris kode pada dasarnya mendidih ke beberapa lusin sistem yang mengandung semua fungsionalitas.
Terlalu Banyak Hal Memberikan Fungsi
Alternatif sebelumnya ketika saya bekerja di basis kode sebelumnya adalah sistem dengan ratusan hingga ribuan objek yang sangat kecil dibandingkan dengan beberapa lusin sistem besar dengan beberapa objek yang digunakan hanya untuk mengirimkan pesan dari satu objek ke objek lainnya (
Message
objek, misalnya, yang memiliki antarmuka publik sendiri). Pada dasarnya itulah yang Anda dapatkan secara analog ketika Anda mengembalikan ECS kembali ke titik di mana komponen memiliki fungsi dan setiap kombinasi unik dari komponen dalam suatu entitas menghasilkan jenis objeknya sendiri. Dan itu akan cenderung menghasilkan fungsi yang lebih kecil, lebih sederhana yang diwarisi dan disediakan oleh kombinasi objek tanpa akhir yang memodelkan ide-ide kecil (Particle
objek vs.Physics System
, mis.). Namun, itu juga cenderung menghasilkan grafik kompleks antar-dependensi yang membuatnya sulit untuk berpikir tentang apa yang terjadi dari tingkat luas, hanya karena ada begitu banyak hal dalam basis kode yang benar-benar dapat melakukan sesuatu dan karena itu dapat melakukan sesuatu yang salah - - tipe yang bukan tipe "data", tetapi tipe "objek" dengan fungsionalitas terkait. Jenis yang berfungsi sebagai data murni tanpa fungsi yang terkait tidak mungkin salah karena mereka tidak dapat melakukan apa pun sendiri.Antarmuka murni tidak banyak membantu masalah kelengkapan ini karena bahkan jika itu membuat "kompilasi-waktu dependensi" tidak terlalu rumit dan memberikan ruang bernapas lebih besar untuk perubahan dan perluasan, itu tidak membuat "dependensi runtime" dan interaksi pun menjadi lebih rumit. Objek klien masih berakhir menjalankan fungsi pada objek akun konkret bahkan jika mereka dipanggil
IAccount
. Polimorfisme dan antarmuka abstrak memiliki kegunaannya, tetapi mereka tidak memisahkan hal-hal dengan cara yang benar-benar membantu Anda beralasan tentang semua efek samping yang dapat berlangsung pada titik tertentu. Untuk mencapai jenis decoupling yang efektif ini, Anda memerlukan basis kode yang memiliki lebih sedikit hal yang mengandung fungsionalitas.Lebih Banyak Data, Lebih Sedikit Fungsi
Jadi saya telah menemukan pendekatan ECS, bahkan jika Anda tidak menerapkannya sepenuhnya, akan sangat membantu, karena ternyata apa yang akan menjadi ratusan objek menjadi hanya data mentah dengan sistem besar, yang dirancang lebih kasar, yang menyediakan semua Kegunaan. Ini memaksimalkan jumlah tipe "data" dan meminimalkan jumlah tipe "objek", dan karena itu benar-benar meminimalkan jumlah tempat di sistem Anda yang benar-benar bisa salah. Hasil akhirnya adalah sistem yang sangat "datar" tanpa grafik ketergantungan yang kompleks, hanya sistem untuk komponen, tidak pernah sebaliknya, dan tidak pernah komponen ke komponen lain. Ini pada dasarnya jauh lebih banyak data mentah dan jauh lebih sedikit abstraksi yang memiliki efek memusatkan dan meratakan fungsi basis kode ke bidang utama, abstraksi kunci.
30 hal yang lebih sederhana tidak selalu lebih mudah untuk dipikirkan dari 1 hal yang lebih kompleks, jika 30 hal yang lebih sederhana itu saling terkait sementara hal yang kompleks itu berdiri sendiri. Jadi saran saya sebenarnya adalah untuk mentransfer kompleksitas dari interaksi antara objek dan lebih ke arah objek bulkier yang tidak harus berinteraksi dengan apa pun untuk mencapai decoupling massa, ke seluruh "sistem" (bukan monolit dan objek dewa, ingatkan Anda, dan bukan kelas dengan 200 metode, tetapi sesuatu yang levelnya jauh lebih tinggi daripada
Message
atauParticle
meskipun memiliki antarmuka minimalis). Dan mendukung tipe data lama yang lebih sederhana. Semakin Anda bergantung pada itu, semakin sedikit kopling yang Anda dapatkan. Bahkan jika itu bertentangan dengan beberapa ide SE, saya telah menemukan itu sangat membantu.sumber
Mungkin itu adalah gejala memilih bahasa pemrograman yang salah.
sumber
Pemahaman yang buruk tentang pola desain cenderung menjadi penyebab utama masalah ini. Salah satu yang terburuk yang pernah saya lihat untuk ini yo-yo'ing dan memantul dari antarmuka ke antarmuka tanpa data konkret di antaranya adalah perpanjangan untuk Oracle's Grid Control.
Jujur terlihat seperti seseorang telah memiliki metode pabrik abstrak dan orgasme pola dekorator di seluruh kode Java saya. Dan itu membuatku merasa hampa dan sendirian.
sumber
Saya juga akan mengingatkan untuk tidak menggunakan fitur-fitur IDE yang membuatnya mudah untuk melakukan hal-hal abstrak.
sumber