Apakah sambungan longgar tanpa pelindung anti-pola?

22

Kopling yang longgar, bagi beberapa pengembang, adalah perangkat lunak yang dirancang dengan baik. Ini tentu hal yang baik ketika membuat kode lebih fleksibel dalam menghadapi perubahan yang mungkin terjadi di masa mendatang, atau menghindari duplikasi kode.

Di sisi lain, upaya untuk secara longgar memasangkan komponen meningkatkan jumlah tipuan dalam suatu program, sehingga meningkatkan kompleksitasnya, seringkali membuatnya lebih sulit untuk dipahami dan sering membuatnya kurang efisien.

Apakah Anda menganggap fokus pada kopling longgar tanpa case penggunaan untuk kopling longgar (seperti menghindari duplikasi kode atau merencanakan perubahan yang kemungkinan akan terjadi di masa mendatang) sebagai anti-pola? Dapatkah kopling longgar jatuh di bawah payung YAGNI?

dsimcha
sumber
1
Sebagian besar manfaat datang dengan biaya. Gunakan jika manfaatnya melebihi biaya.
LennyProgrammers
4
Anda lupa sisi lain dari koin pelepas longgar, dan yang high cohesionsatu tanpa yang lain adalah pemborosan usaha dan ilustrasi mendasar kurangnya pemahaman keduanya.

Jawaban:

13

Agak.

Kadang-kadang lepas kopling yang datang tanpa banyak usaha baik-baik saja, bahkan jika Anda tidak memiliki persyaratan khusus yang menuntut beberapa modul dipisahkan. Buah yang menggantung rendah, seolah-olah.

Di sisi lain, terlalu banyak rekayasa untuk jumlah perubahan konyol akan banyak kompleksitas dan upaya yang tidak perlu. YAGNI, seperti yang Anda katakan, mengenai kepalanya.

Fishtoaster
sumber
22

Apakah praktik pemrograman X baik atau buruk? Jelas, jawabannya selalu "itu tergantung."

Jika Anda melihat kode Anda, bertanya-tanya "pola" apa yang bisa Anda masukkan, maka Anda salah melakukannya.

Jika Anda sedang membangun perangkat lunak Anda sehingga objek yang tidak terkait tidak saling bermain-main, maka Anda melakukannya dengan benar.

Jika Anda "merekayasa" solusi Anda sehingga dapat diperpanjang dan diubah tanpa batas, maka Anda sebenarnya membuatnya lebih rumit.

Saya pikir pada akhirnya, Anda hanya memiliki satu kebenaran: apakah lebih atau kurang rumit untuk memisahkan objek? Jika kurang rumit untuk memasangkan mereka, maka itu adalah solusi yang tepat. Jika kurang rumit untuk memisahkan mereka, maka itu adalah solusi yang tepat.

(Saat ini saya bekerja di basis kode yang cukup kecil yang melakukan pekerjaan sederhana dengan cara yang sangat rumit, dan bagian dari apa yang membuatnya sangat rumit adalah kurangnya pemahaman tentang istilah "penggandengan" dan "kohesi" pada bagian asli pengembang.)

dash-tom-bang
sumber
4
Saya melakukan ini beberapa hari yang lalu: Saya pikir saya akan memerlukan beberapa tipuan antara dua kelas "untuk berjaga-jaga". Lalu aku melukai kepalaku mencoba men-debug sesuatu, merobek tipuan, dan jauh lebih bahagia.
Frank Shearar
3

Saya pikir apa yang Anda maksudkan di sini adalah konsep kohesi . Apakah kode ini memiliki tujuan yang baik? Bisakah saya menginternalisasi tujuan itu dan memahami "gambaran besar" dari apa yang terjadi?

Ini dapat menyebabkan kode yang sulit untuk diikuti, bukan hanya karena ada lebih banyak file sumber (dengan asumsi ini adalah kelas yang terpisah), tetapi karena tidak ada satu kelas pun yang memiliki tujuan.

Dari perspektif lincah, saya mungkin menyarankan bahwa kopling longgar seperti itu akan menjadi anti-pola. Tanpa kohesi, atau bahkan menggunakan case untuk itu, Anda tidak dapat menulis tes unit yang masuk akal, dan tidak dapat memverifikasi tujuan kode. Sekarang, kode gesit dapat menyebabkan kopling longgar, misalnya ketika pengembangan berbasis tes digunakan. Tetapi jika tes yang tepat dibuat, dalam urutan yang benar, maka kemungkinan ada kohesi yang baik dan kopling longgar. Dan Anda hanya berbicara tentang kasus-kasus ketika jelas tidak ada kohesi di sana.

Sekali lagi dari perspektif lincah, Anda tidak ingin tingkat tipuan buatan ini karena sia-sia upaya pada sesuatu yang mungkin tidak akan diperlukan pula. Jauh lebih mudah untuk refactor ketika kebutuhannya nyata.

Secara keseluruhan, Anda ingin kopling tinggi di dalam modul Anda, dan lepas kopling di antaranya. Tanpa kopling tinggi, Anda mungkin tidak memiliki kohesi.

Macneil
sumber
1

Untuk sebagian besar pertanyaan seperti ini, jawabannya adalah "itu tergantung." Secara keseluruhan, jika saya dapat membuat desain secara logis longgar digabungkan dengan cara yang masuk akal, tanpa overhead utama untuk melakukannya, saya akan melakukannya. Menghindari penggandaan yang tidak perlu dalam kode, menurut saya, adalah tujuan desain yang sepenuhnya berharga.

Setelah sampai pada situasi di mana sepertinya komponen harus secara logis dipasangkan dengan erat, saya akan mencari argumen yang menarik sebelum saya mulai memecahnya.

Saya kira prinsip saya bekerja dengan sebagian besar jenis latihan ini adalah salah satu inersia. Saya punya ide bagaimana saya ingin kode saya bekerja dan jika saya bisa melakukannya tanpa membuat hidup lebih sulit maka saya akan melakukannya. Jika melakukannya akan membuat pengembangan lebih sulit tetapi pemeliharaan dan pekerjaan di masa depan lebih mudah. ​​Saya akan mencoba dan mencari tahu apakah itu akan lebih bekerja sepanjang masa kode dan menggunakannya sebagai panduan saya. Kalau tidak, itu perlu menjadi titik desain yang disengaja untuk menjadi layak untuk pergi bersama.

glenatron
sumber
1

Jawaban sederhananya adalah kopling longgar bagus jika dilakukan dengan benar.

Jika prinsip satu fungsi, satu tujuan diikuti maka harus cukup mudah untuk mengikuti apa yang sedang terjadi. Juga, kode pasangan yang longgar mengikuti sebagai hal yang biasa tanpa usaha apa pun.

Aturan desain sederhana: 1. jangan membangun pengetahuan beberapa item menjadi satu titik (seperti yang ditunjukkan di mana-mana, tergantung) kecuali Anda membangun antarmuka fasad. 2. satu fungsi - satu tujuan (tujuan itu dapat multi-faceted seperti dalam fasad) 3. satu modul - satu set fungsi saling terkait yang jelas - satu tujuan yang jelas 4. jika Anda tidak dapat dengan mudah mengujinya maka unit tersebut tidak memiliki tujuan sederhana

Semua komentar tentang lebih mudah direvisi nanti adalah banyak cod. Begitu pengetahuan itu terbangun di banyak tempat, terutama dalam sistem terdistribusi, biaya refactoring, sinkronisasi peluncuran, dan hampir setiap biaya lain menghancurkannya sehingga tidak masuk akal bahwa dalam kebanyakan kasus, sistem akhirnya dihancurkan karena itu.

Yang menyedihkan tentang pengembangan perangkat lunak akhir-akhir ini adalah 90% orang mengembangkan sistem baru dan tidak memiliki kemampuan untuk memahami sistem lama, dan tidak pernah ada ketika sistem telah mencapai kondisi kesehatan yang buruk karena terus-menerus melakukan refactoring potongan-potongan.

sweetfa
sumber
0

Tidak masalah seberapa erat satu hal dengan yang lain jika hal lainnya tidak pernah berubah. Saya telah menemukan bahwa umumnya lebih produktif selama bertahun-tahun untuk fokus pada mencari lebih sedikit alasan untuk hal-hal untuk berubah, untuk mencari stabilitas, daripada untuk membuatnya lebih mudah untuk berubah dengan mencoba mencapai bentuk penggabungan yang paling longgar. Decoupling yang saya temukan sangat berguna, sampai pada titik di mana saya kadang-kadang menyukai duplikasi kode sederhana untuk memisahkan paket. Sebagai contoh dasar, saya punya pilihan untuk menggunakan perpustakaan matematika saya untuk mengimplementasikan perpustakaan gambar. Saya tidak dan hanya menggandakan beberapa fungsi matematika dasar yang mudah untuk disalin.

Sekarang perpustakaan gambar saya benar-benar independen dari perpustakaan matematika dengan cara di mana tidak peduli apa pun perubahan yang saya buat untuk lib matematika saya, itu tidak akan mempengaruhi perpustakaan gambar. Itu menempatkan stabilitas sebagai yang utama dan terpenting. Pustaka gambar sekarang lebih stabil, karena memiliki lebih sedikit alasan untuk berubah secara drastis, karena dipisah dari pustaka lain yang dapat berubah (selain pustaka standar C yang semoga tidak boleh berubah). Sebagai bonus juga mudah untuk digunakan ketika itu hanya sebuah perpustakaan mandiri yang tidak perlu menarik banyak lib lain untuk membangun dan menggunakannya.

Stabilitas sangat membantu saya. Saya suka membangun koleksi kode yang telah teruji baik yang memiliki lebih sedikit dan lebih sedikit alasan untuk berubah di masa depan. Itu bukan mimpi pipa; Saya memiliki kode C yang telah saya gunakan dan gunakan lagi sejak akhir 80-an yang tidak berubah sama sekali sejak itu. Memang diakui hal-hal tingkat rendah seperti pixel-oriented dan kode terkait geometri sementara banyak hal tingkat tinggi saya menjadi usang, tetapi itu adalah sesuatu yang masih banyak membantu untuk dimiliki. Itu hampir selalu berarti perpustakaan yang bergantung pada semakin sedikit hal, jika tidak ada yang eksternal sama sekali. Keandalan naik dan naik jika perangkat lunak Anda semakin tergantung pada fondasi stabil yang menemukan sedikit atau tidak ada alasan untuk berubah. Lebih sedikit bagian yang bergerak benar-benar bagus, bahkan jika dalam praktiknya bagian yang bergerak jauh lebih besar jumlahnya daripada bagian yang stabil.

Kopling longgar berada dalam nada yang sama, tetapi saya sering menemukan bahwa kopling longgar jauh lebih stabil daripada kopling tidak. Kecuali jika Anda bekerja dalam tim dengan desainer dan klien antarmuka yang jauh lebih unggul yang tidak berubah pikiran daripada yang pernah saya kerjakan, bahkan antarmuka murni sering menemukan alasan untuk berubah dengan cara yang masih menyebabkan kerusakan cascading di seluruh kode. Gagasan bahwa stabilitas dapat dicapai dengan mengarahkan dependensi ke abstrak daripada beton hanya berguna jika desain antarmuka lebih mudah untuk mendapatkan yang benar saat pertama kali daripada implementasi. Saya sering menemukannya terbalik ketika pengembang mungkin telah menciptakan implementasi yang sangat baik, jika tidak luar biasa, mengingat persyaratan desain yang menurut mereka harus dipenuhi, hanya untuk menemukan di masa depan bahwa persyaratan desain berubah sepenuhnya.

Jadi saya suka mendukung stabilitas dan decoupling lengkap sehingga saya setidaknya dapat dengan percaya diri mengatakan, "Perpustakaan kecil yang terisolasi ini yang telah digunakan selama bertahun-tahun dan diamankan dengan pengujian menyeluruh hampir tidak memiliki kemungkinan memerlukan perubahan apa pun yang terjadi di dunia luar yang kacau ini. . " Ini memberi saya sedikit kewarasan tidak peduli apa perubahan desain yang disebut untuk luar.

Kopling dan Stabilitas, Contoh ECS

Saya juga suka sistem entitas-komponen dan mereka memperkenalkan banyak kopling ketat karena semua ketergantungan sistem pada komponen mengakses dan memanipulasi data mentah secara langsung, seperti:

masukkan deskripsi gambar di sini

Semua dependensi di sini cukup ketat karena komponen hanya mengekspos data mentah. Ketergantungan tidak mengalir ke abstraksi, mereka mengalir ke data mentah yang berarti bahwa setiap sistem memiliki jumlah pengetahuan maksimum yang mungkin tentang setiap jenis komponen yang mereka minta untuk akses. Komponen tidak memiliki fungsionalitas dengan semua sistem mengakses dan merusak data mentah. Namun, sangat mudah untuk berpikir tentang sistem seperti ini karena sangat datar. Jika suatu tekstur keluar edan, maka Anda tahu dengan sistem ini segera bahwa hanya komponen rendering dan pengecatan yang mengakses komponen tekstur, dan Anda mungkin dapat dengan cepat mengesampingkan sistem rendering karena hanya membaca dari tekstur secara konseptual.

Sementara alternatif yang digabungkan secara longgar mungkin adalah ini:

masukkan deskripsi gambar di sini

... dengan semua dependensi yang mengalir ke fungsi abstrak, bukan data, dan setiap hal dalam diagram itu memperlihatkan antarmuka publik dan fungsionalitasnya sendiri. Di sini semua dependensi mungkin sangat longgar. Objek mungkin bahkan tidak secara langsung bergantung satu sama lain dan berinteraksi satu sama lain melalui antarmuka murni. Masih sangat sulit untuk berpikir tentang sistem ini, terutama jika ada yang salah, mengingat jalinan interaksi yang kompleks. Juga akan ada lebih banyak interaksi (lebih banyak kopling, meskipun lebih longgar) daripada ECS karena entitas harus tahu tentang komponen yang mereka agregat, bahkan jika mereka hanya tahu tentang antarmuka publik abstrak masing-masing.

Juga jika ada perubahan desain untuk apa pun, Anda mendapatkan lebih banyak kerusakan berjenjang daripada ECS, dan biasanya akan ada lebih banyak alasan dan godaan untuk perubahan desain karena setiap hal mencoba memberikan antarmuka dan abstraksi berorientasi objek yang bagus. Itu segera datang dengan gagasan bahwa masing-masing dan setiap hal kecil akan mencoba untuk memaksakan kendala dan keterbatasan pada desain, dan kendala-kendala itu sering kali yang menuntut perubahan desain. Fungsionalitas jauh lebih terbatas dan harus membuat asumsi desain lebih banyak daripada data mentah.

Saya telah menemukan dalam praktiknya jenis sistem ECS "flat" di atas jauh lebih mudah untuk dipikirkan daripada bahkan sistem yang paling longgar digabungkan dengan sarang laba-laba kompleks yang longgar dan, yang paling penting bagi saya, saya menemukan beberapa alasan. untuk versi ECS yang perlu mengubah komponen yang ada karena komponen bergantung tidak memiliki tanggung jawab kecuali untuk menyediakan data yang sesuai yang diperlukan agar sistem berfungsi. Bandingkan kesulitan mendesain IMotionantarmuka murni dan objek gerak konkret yang mengimplementasikan antarmuka yang menyediakan fungsionalitas canggih sambil mencoba mempertahankan invarian terhadap data pribadi vs. komponen gerak yang hanya perlu menyediakan data mentah yang relevan untuk menyelesaikan masalah dan tidak repot dengan fungsionalitas.

Fungsionalitas jauh lebih sulit untuk mendapatkan yang benar daripada data, itulah sebabnya saya pikir seringkali lebih baik untuk mengarahkan aliran ketergantungan terhadap data. Lagi pula, berapa banyak perpustakaan vektor / matriks di luar sana? Berapa banyak dari mereka yang menggunakan representasi data yang persis sama dan hanya berbeda secara fungsional? Tak terhitung, namun kita masih memiliki begitu banyak meskipun representasi data yang identik karena kita ingin perbedaan fungsi yang halus. Berapa banyak perpustakaan gambar di luar sana? Berapa banyak dari mereka yang merepresentasikan piksel dengan cara yang berbeda dan unik? Hampir tidak ada, dan sekali lagi menunjukkan bahwa fungsionalitas jauh lebih tidak stabil dan cenderung terhadap perubahan desain daripada data dalam banyak skenario. Tentu saja di beberapa titik kita membutuhkan fungsionalitas, tetapi Anda dapat merancang sistem di mana sebagian besar dependensi mengalir ke data, dan tidak menuju abstraksi atau fungsionalitas secara umum. Seperti itu akan memprioritaskan stabilitas di atas kopling.

Fungsi paling stabil yang pernah saya tulis (jenis yang saya gunakan dan gunakan kembali sejak akhir 80-an tanpa harus mengubahnya sama sekali) adalah semua yang bergantung pada data mentah, seperti fungsi geometri yang baru saja menerima serangkaian mengapung dan bilangan bulat, bukan yang bergantung pada Meshobjek atau IMeshantarmuka yang kompleks , atau penggandaan vektor / matriks yang hanya bergantung pada float[]atau double[], bukan yang bergantung pada FancyMatrixObjectWhichWillRequireDesignChangesNextYearAndDeprecateWhatWeUse.


sumber