Saya mencoba mempelajari GRASP dan saya menemukan ini menjelaskan (di sini di halaman 3 ) tentang Kopling Rendah dan saya sangat terkejut ketika saya menemukan ini:
Pertimbangkan metode
addTrack
untuk suatuAlbum
kelas, dua metode yang mungkin adalah:
addTrack( Track t )
dan
addTrack( int no, String title, double duration )
Metode mana yang mengurangi kopling? Yang kedua tidak, karena kelas yang menggunakan kelas Album tidak harus tahu kelas Track. Secara umum, parameter ke metode harus menggunakan tipe dasar (int, char ...) dan kelas dari paket java. *.
Saya cenderung setuju dengan ini; Saya percaya addTrack(Track t)
lebih baik daripada addTrack(int no, String title, double duration)
karena berbagai alasan:
Itu selalu lebih baik untuk metode sebagai parameter sesedikit mungkin (menurut Kode Bersih Paman Bob tidak ada atau lebih disukai, 2 dalam beberapa kasus dan 3 dalam kasus khusus; lebih dari 3 kebutuhan refactoring - ini tentu saja rekomendasi bukan aturan holly) .
Jika
addTrack
merupakan metode antarmuka, dan persyaratan yang dibutuhkanTrack
harus memiliki lebih banyak informasi (misalnya tahun atau genre) maka antarmuka perlu diubah dan agar metode tersebut harus mendukung parameter lain.Enkapsulasi rusak; jika
addTrack
ada dalam sebuah antarmuka, maka seharusnya tidak tahu internalTrack
.Ini sebenarnya lebih digabungkan dengan cara kedua, dengan banyak parameter. Misalkan
no
parameter perlu diubah dariint
menjadilong
karena ada lebih dariMAX_INT
trek (atau untuk alasan apa pun); maka keduanyaTrack
dan metode perlu diubah sementara jika metodeaddTrack(Track track)
hanyaTrack
akan diubah.
Keempat argumen itu sebenarnya terhubung satu sama lain, dan beberapa di antaranya merupakan konsekuensi dari yang lain.
Pendekatan mana yang lebih baik?
Jawaban:
Nah, tiga poin pertama Anda sebenarnya tentang prinsip-prinsip lain selain penggabungan. Anda selalu harus menemukan keseimbangan antara prinsip-prinsip desain yang sering bertentangan.
Poin keempat Anda adalah tentang pemasangan, dan saya sangat setuju dengan Anda. Coupling adalah tentang aliran data antar modul. Jenis wadah yang mengalir data sebagian besar tidak material. Melewati durasi sebagai gandanya bukan sebagai bidang
Track
tidak menghilangkan kebutuhan untuk melewatinya. Modul masih perlu berbagi jumlah data yang sama, dan masih memiliki jumlah kopling yang sama.Dia juga gagal untuk mempertimbangkan semua kopling dalam sistem sebagai agregat. Sementara memperkenalkan
Track
kelas diakui menambah ketergantungan lain antara dua modul individu, itu dapat secara signifikan mengurangi kopling sistem , yang merupakan ukuran penting di sini.Sebagai contoh, mempertimbangkan "Tambahkan ke Daftar Putar" tombol dan
Playlist
objek. MemperkenalkanTrack
objek dapat dianggap meningkatkan kopling jika Anda hanya mempertimbangkan kedua objek tersebut. Anda sekarang memiliki tiga kelas yang saling tergantung bukan dua. Namun, itu bukan keseluruhan sistem Anda. Anda juga perlu mengimpor trek, memutar trek, menampilkan trek, dll. Menambahkan satu kelas lagi ke campuran itu dapat diabaikan.Sekarang pertimbangkan untuk menambahkan dukungan untuk memainkan trek melalui jaringan, bukan hanya secara lokal. Anda hanya perlu membuat
NetworkTrack
objek yang sesuai dengan antarmuka yang sama. TanpaTrack
objek, Anda harus membuat fungsi di mana-mana seperti:Itu secara efektif menggandakan kopling Anda, membutuhkan bahkan modul yang tidak peduli tentang hal-hal khusus jaringan untuk tetap melacaknya, agar dapat meneruskannya.
Tes efek riak Anda bagus untuk menentukan jumlah kopling Anda yang sebenarnya. Yang kami khawatirkan adalah membatasi tempat-tempat yang terkena dampak perubahan.
sumber
Rekomendasi saya adalah:
Menggunakan
tapi pastikan itu
ITrack
adalah antarmuka dan bukan kelas yang konkret.Album tidak tahu internal
ITrack
implementors. Ini hanya digabungkan dengan kontrak yang ditentukan olehITrack
.Saya pikir ini adalah solusi yang menghasilkan jumlah kopling paling sedikit.
sumber
Track
menjadi bodoh atau pintar.Track
adalah konkret.ITrack
antarmuka adalah abstraksi. Dengan begitu Anda akan dapat memiliki berbagai jenis Trek di masa mendatang, selama mereka mematuhinyaITrack
.Saya berpendapat bahwa metode contoh kedua kemungkinan besar meningkatkan kopling, karena kemungkinan besar adalah instantiating objek Track dan menyimpannya dalam objek Album saat ini. (Seperti yang disarankan dalam komentar saya di atas, saya akan menganggapnya melekat bahwa kelas Album akan memiliki konsep kelas Track di suatu tempat di dalamnya.)
Metode contoh pertama mengasumsikan bahwa suatu Track sedang dipakai di luar kelas Album, jadi setidaknya, kita dapat mengasumsikan bahwa instantiasi dari kelas Track tidak digabungkan ke kelas Album.
Jika praktik terbaik menyarankan bahwa kita tidak pernah memiliki satu referensi kelas kelas kedua, keseluruhan pemrograman berorientasi objek akan dibuang keluar jendela.
sumber
Coupling hanyalah salah satu dari banyak aspek untuk mencoba mendapatkan dalam kode Anda. Dengan mengurangi sambungan, Anda tidak perlu meningkatkan program Anda. Secara umum, ini adalah praktik terbaik, tetapi dalam contoh khusus ini, mengapa tidak
Track
diketahui?Dengan menggunakan
Track
kelas untuk diteruskanAlbum
, Anda membuat kode Anda lebih mudah dibaca, tetapi yang lebih penting, seperti yang Anda sebutkan, Anda mengubah daftar parameter statis menjadi objek dinamis. Itu pada akhirnya membuat antarmuka Anda jauh lebih dinamis.Anda menyebutkan bahwa enkapsulasi rusak, tetapi tidak.
Album
harus mengetahui bagian dalamTrack
, dan jika Anda tidak menggunakan objek,Album
harus mengetahui setiap informasi yang diteruskan sebelum dapat memanfaatkannya semua sama. Penelepon harus mengetahui internalTrack
juga, karena ia harus membangunTrack
objek, tetapi penelepon harus mengetahui informasi ini semua sama jika diteruskan langsung ke metode. Dengan kata lain, jika keuntungan enkapsulasi adalah tidak mengetahui isi suatu objek, itu tidak mungkin digunakan dalam kasus ini karenaAlbum
harus memanfaatkanTrack
informasi sama saja.Di mana Anda tidak ingin menggunakan
Track
adalah jikaTrack
berisi logika internal yang Anda tidak ingin pemanggil memiliki akses. Dengan kata lain, jikaAlbum
kelas yang digunakan seorang programmer menggunakan perpustakaan Anda, Anda tidak ingin dia menggunakannyaTrack
jika Anda mengatakannya, panggil metode untuk bertahan di database. Masalah sebenarnya dengan ini terletak pada kenyataan bahwa antarmuka terjerat dengan model.Untuk memperbaiki masalah, Anda harus memisahkan
Track
komponen antarmuka dan komponen logikanya, membuat dua kelas terpisah. Untuk penelepon,Track
menjadi kelas ringan yang dimaksudkan untuk menyimpan informasi dan menawarkan optimasi kecil (data yang dihitung dan / atau nilai default). Di dalamAlbum
, Anda akan menggunakan kelas bernamaTrackDAO
untuk melakukan angkat berat yang terkait dengan menyimpan informasi dariTrack
ke database.Tentu saja, ini hanya sebuah contoh. Saya yakin ini bukan kasus Anda sama sekali, jadi jangan ragu untuk menggunakan
Track
rasa bersalah. Ingatlah untuk selalu mengingat penelepon Anda ketika Anda sedang membangun kelas dan untuk membuat antarmuka bila diperlukan.sumber
Keduanya benar
adalah lebih baik (karena Anda sudah argumented) sementara
adalah kurang ditambah karena kode yang menggunakan
addTrack
tidak perlu tahu bahwa adaTrack
kelas. Track dapat diubah namanya misalnya tanpa perlu memperbarui kode panggilan.Sementara Anda berbicara tentang kode yang lebih mudah dibaca / dipelihara, artikel ini berbicara tentang pemasangan . Kode kurang digabungkan tidak selalu lebih mudah untuk diterapkan dan dipahami.
sumber
Kopling Rendah tidak berarti Kopling Tidak . Sesuatu, di suatu tempat, harus tahu tentang objek di tempat lain dalam basis kode, dan semakin Anda mengurangi ketergantungan pada objek "kustom", semakin banyak alasan yang Anda berikan untuk mengubah kode. Apa yang penulis kutip adalah mempromosikan dengan fungsi kedua kurang digabungkan, tetapi juga kurang berorientasi objek, yang bertentangan dengan seluruh gagasan GRASP sebagai metodologi desain berorientasi objek . Intinya adalah bagaimana merancang sistem sebagai kumpulan objek dan interaksinya; Menghindarinya sama seperti mengajari Anda cara mengendarai mobil dengan mengatakan Anda harus mengendarai sepeda saja.
Sebagai gantinya, jalan yang tepat adalah untuk mengurangi ketergantungan pada benda - benda konkret , yang merupakan teori "lepas kopling". Semakin sedikit jenis beton tertentu yang harus dimiliki suatu metode, semakin baik. Hanya dengan pernyataan itu, opsi pertama sebenarnya kurang digabungkan, karena metode kedua mengambil jenis yang lebih sederhana harus tahu tentang semua jenis yang lebih sederhana. Tentu mereka built-in, dan kode di dalam metode mungkin harus peduli, tetapi tanda tangan metode dan penelepon metode itu pasti tidak . Mengubah salah satu dari parameter ini yang berkaitan dengan trek audio konseptual akan membutuhkan lebih banyak perubahan ketika terpisah dibandingkan ketika mereka terkandung dalam objek Track (yang merupakan titik objek; enkapsulasi).
Selangkah lebih maju, jika Track diharapkan akan diganti dengan sesuatu yang melakukan pekerjaan yang sama dengan lebih baik, mungkin sebuah antarmuka yang mendefinisikan fungsionalitas yang diperlukan adalah dalam urutan, sebuah ITrack. Itu dapat memungkinkan untuk implementasi yang berbeda seperti "AnalogTrack", "CdTrack" dan "Mp3Track" yang memberikan informasi tambahan yang lebih spesifik untuk format-format tersebut, sambil tetap memberikan paparan data dasar dari ITrack yang secara konseptual mewakili "track"; sub-bagian audio yang terbatas. Track juga bisa menjadi kelas dasar abstrak, tetapi ini mengharuskan Anda untuk selalu ingin menggunakan implementasi yang melekat dalam Track; implementasikan kembali sebagai BetterTrack dan sekarang Anda harus mengubah parameter yang diharapkan.
Demikianlah aturan emasnya; program dan komponen kode mereka akan selalu memiliki alasan untuk berubah. Anda tidak dapat menulis program yang tidak akan memerlukan kode pengeditan yang telah Anda tulis untuk menambahkan sesuatu yang baru atau mengubah perilakunya. Tujuan Anda, dalam metodologi (GRASP, SOLID, setiap akronim atau kata kunci yang dapat Anda pikirkan) hanya untuk mengidentifikasi hal-hal yang akan harus berubah dari waktu ke waktu, dan merancang sistem sehingga perubahan tersebut adalah sebagai mudah untuk membuat mungkin (Diterjemahkan; menyentuh beberapa baris kode dan memengaruhi sesedikit mungkin area lain dari sistem di luar cakupan perubahan yang Anda maksudkan). Contoh kasus, apa yang paling mungkin berubah adalah Track akan mendapatkan lebih banyak anggota data yang addTrack () mungkin peduli atau tidak peduli, tidak Track itu akan diganti dengan BetterTrack.
sumber