Mari kita lihat ini secara praktis
Obj 3
sekarang tahu Obj 4
ada. Terus? Kenapa kita peduli?
Kata DIP
"Modul tingkat tinggi seharusnya tidak bergantung pada modul tingkat rendah. Keduanya harus bergantung pada abstraksi."
OK tapi, bukankah semua objek abstraksi?
DIP juga mengatakan
"Abstraksi tidak harus bergantung pada detail. Detail harus bergantung pada abstraksi."
OK tapi, jika objek saya dienkapsulasi dengan benar bukankah itu menyembunyikan detail?
Beberapa orang suka membabi buta bersikeras bahwa setiap objek membutuhkan antarmuka kata kunci. Saya bukan salah satu dari mereka. Saya suka secara membabi buta bersikeras bahwa jika Anda tidak akan menggunakannya sekarang Anda perlu rencana untuk berurusan dengan membutuhkan sesuatu seperti mereka nanti.
Jika kode Anda sepenuhnya dapat di-refactor pada setiap rilis, Anda bisa mengekstrak antarmuka nanti jika Anda membutuhkannya. Jika Anda telah menerbitkan kode yang tidak ingin Anda kompilasi ulang dan mendapati diri Anda berharap Anda berbicara melalui antarmuka, Anda memerlukan rencana.
Obj 3
tahu Obj 4
ada. Tapi apakah Obj 3
tahu kalau Obj 4
beton?
Ini di sini adalah mengapa sangat bagus untuk TIDAK menyebar ke new
mana-mana. Jika Obj 3
tidak tahu apakah Obj 4
konkret, kemungkinan karena itu tidak membuatnya, maka jika Anda menyelinap masuk dan berubah Obj 4
menjadi kelas abstrak Obj 3
tidak akan peduli.
Jika Anda bisa melakukan itu, maka Obj 4
abstrak sepenuhnya selama ini. Satu-satunya hal yang membuat antarmuka di antara mereka dari awal membuat Anda adalah jaminan bahwa seseorang tidak akan sengaja menambahkan kode yang memberikan yang Obj 4
konkret saat ini. Konstruktor yang dilindungi dapat mengurangi risiko itu tetapi itu mengarah ke pertanyaan lain:
Apakah Obj 3 dan Obj 4 dalam paket yang sama?
Objek sering dikelompokkan dalam beberapa cara (paket, namespace, dll). Ketika dikelompokkan dengan bijak, ubahlah dampak yang lebih mungkin terjadi dalam suatu kelompok daripada lintas kelompok.
Saya suka mengelompokkan berdasarkan fitur. Jika Obj 3
dan Obj 4
berada di grup dan lapisan yang sama, sangat tidak mungkin Anda telah menerbitkan satu dan tidak ingin membuatnya kembali sementara hanya perlu mengubah yang lain. Itu berarti benda-benda ini cenderung mendapat manfaat dari memiliki abstraksi yang diletakkan di antara mereka sebelum memiliki kebutuhan yang jelas.
Jika Anda melewati batas grup, meskipun itu ide yang bagus untuk membiarkan objek di kedua sisi berbeda secara independen.
Seharusnya sesederhana itu, tetapi sayangnya Java dan C # telah membuat pilihan yang tidak menguntungkan yang menyulitkan ini.
Dalam C # itu tradisi untuk memberi nama setiap antarmuka kata kunci dengan I
awalan. Itu memaksa klien untuk TAHU mereka berbicara dengan antarmuka kata kunci. Itu mengacaukan rencana refactoring.
Di Jawa tradisi menggunakan pola penamaan yang lebih baik: FooImple implements Foo
Namun, ini hanya membantu pada tingkat kode sumber karena Java mengkompilasi antarmuka kata kunci ke biner yang berbeda. Itu berarti ketika Anda refactor Foo
dari klien konkret ke abstrak yang tidak memerlukan satu karakter kode yang diubah masih harus dikompilasi ulang.
BUGS dalam bahasa-bahasa khusus inilah yang membuat orang tidak bisa menunda abstraksi formal sampai mereka benar-benar membutuhkannya. Anda tidak mengatakan bahasa apa yang Anda gunakan tetapi mengerti ada beberapa bahasa yang tidak memiliki masalah ini.
Anda tidak mengatakan bahasa apa yang Anda gunakan jadi saya hanya akan mendorong Anda untuk menganalisis bahasa dan situasi Anda dengan cermat sebelum Anda memutuskan itu akan menjadi antarmuka kata kunci di mana-mana.
Prinsip YAGNI memainkan peran kunci di sini. Tetapi begitu juga "Tolong buat sulit untuk menembak diri sendiri di kaki".