Salah satu prinsip OOP yang saya temui adalah: -Merumuskan apa yang bervariasi.
Saya mengerti apa arti harfiah dari frasa tersebut, yaitu menyembunyikan apa yang berbeda-beda. Namun, saya tidak tahu persis bagaimana itu berkontribusi pada desain yang lebih baik. Adakah yang bisa menjelaskannya menggunakan contoh yang baik?
design
design-patterns
object-oriented
encapsulation
Haris Ghauri
sumber
sumber
I don't know how exactly would it contribute to a better design
Enkapsulasi detail adalah tentang kopling longgar antara "model" dan detail implementasi. Semakin kurang terikat adalah "model" untuk detail implementasi, semakin fleksibel solusinya. Dan itu membuatnya lebih mudah untuk mengembangkannya. "Abstrak sendiri dari detail".Jawaban:
Anda dapat menulis kode yang terlihat seperti ini:
atau Anda dapat menulis kode yang terlihat seperti ini:
Jika apa yang dienkapsulasi berbeda-beda maka Anda tidak perlu khawatir. Anda hanya khawatir tentang apa yang Anda butuhkan dan apa pun yang Anda gunakan angka bagaimana melakukan apa yang benar-benar Anda butuhkan berdasarkan apa yang bervariasi.
Meringkas apa yang bervariasi dan Anda tidak perlu menyebarkan kode di sekitar yang peduli tentang apa yang bervariasi. Anda hanya mengatur hewan peliharaan menjadi tipe tertentu yang tahu bagaimana berbicara sebagai tipe itu dan setelah itu Anda bisa melupakan jenis mana dan memperlakukannya seperti hewan peliharaan. Anda tidak perlu bertanya tipe yang mana.
Anda mungkin berpikir tipe encapsulated karena seorang pengambil diperlukan untuk mengaksesnya. Bukan saya. Getter's tidak benar-benar merangkum. Mereka hanya menguap ketika seseorang merusak enkapsulasi Anda. Mereka adalah dekorator yang bagus seperti kait berorientasi aspek yang paling sering digunakan sebagai kode debugging. Tidak peduli bagaimana Anda mengirisnya, Anda masih mengekspos tipenya.
Anda mungkin melihat contoh ini dan berpikir saya sedang mengkonfimasikan polimorfisme dan enkapsulasi. Bukan saya. Saya menyatukan "apa yang bervariasi" dan "detail".
Fakta bahwa hewan peliharaan Anda adalah anjing adalah detail. Yang mungkin berbeda untuk Anda. Yang mungkin tidak. Namun yang pasti berbeda dari orang ke orang. Kecuali kami percaya perangkat lunak ini hanya akan digunakan oleh pecinta anjing, pintar memperlakukan anjing sebagai detail dan merangkumnya. Dengan cara itu beberapa bagian dari sistem sangat tidak menyadari anjing dan tidak akan terkena dampak ketika kita bergabung dengan "beo adalah kita".
Pisahkan, pisahkan, dan sembunyikan detail dari sisa kode. Jangan biarkan pengetahuan detail menyebar melalui sistem Anda dan Anda akan mengikuti "merangkum apa yang bervariasi" dengan baik.
sumber
"Bervariasi" di sini berarti "dapat berubah seiring waktu karena perubahan persyaratan". Ini adalah prinsip desain inti: Untuk memisahkan dan mengisolasi bagian-bagian kode atau data yang mungkin harus diubah secara terpisah di masa mendatang. Jika satu persyaratan berubah, idealnya hanya mengharuskan kami untuk mengubah kode terkait di satu tempat. Tetapi jika basis kode dirancang dengan buruk, yaitu sangat saling berhubungan dan logika untuk persyaratan tersebar di banyak tempat, maka perubahan akan sulit dan memiliki risiko tinggi menyebabkan efek yang tidak terduga.
Katakanlah Anda memiliki aplikasi yang menggunakan penghitungan pajak penjualan di banyak tempat. Jika tarif pajak penjualan berubah, apa yang Anda inginkan:
tarif pajak penjualan adalah literal hardcode di mana-mana dalam aplikasi tempat pajak penjualan dihitung.
tarif pajak penjualan adalah konstanta global, yang digunakan di mana-mana dalam aplikasi tempat pajak penjualan dihitung.
ada satu metode yang disebut
calculateSalesTax(product)
yang merupakan satu-satunya tempat tarif pajak penjualan digunakan.tarif pajak penjualan ditentukan dalam file konfigurasi atau bidang basis data.
Karena tarif pajak penjualan dapat berubah karena keputusan politik yang independen dari persyaratan lain, kami lebih suka mengisolasi dalam konfigurasi, sehingga dapat diubah tanpa memengaruhi kode apa pun. Tetapi dapat dibayangkan logika untuk menghitung pajak penjualan dapat berubah, mis. Tarif yang berbeda untuk produk yang berbeda, jadi kami juga ingin agar logika perhitungannya dienkapsulasi. Konstanta global mungkin tampak seperti ide yang baik, tetapi sebenarnya buruk, karena mungkin mendorong penggunaan pajak penjualan tempat yang berbeda dalam program daripada di satu tempat.
Sekarang perhatikan konstanta lain, Pi, yang juga digunakan di banyak tempat dalam kode. Apakah prinsip desain yang sama berlaku? Tidak, karena Pi tidak akan berubah. Mengekstraknya ke file konfigurasi atau bidang database tidak hanya menambah kerumitan yang tidak perlu (dan semua hal lain dianggap sama, kami lebih suka kode yang paling sederhana). Masuk akal untuk menjadikannya sebuah konstanta global daripada hardcode di beberapa tempat untuk menghindari ketidakkonsistenan dan meningkatkan keterbacaan.
Intinya adalah, jika kita hanya melihat bagaimana program itu bekerja sekarang , tarif pajak penjualan dan Pi adalah setara, keduanya adalah konstanta. Hanya ketika kita mempertimbangkan apa yang mungkin berbeda di masa depan , kita menyadari bahwa kita harus memperlakukan mereka secara berbeda dalam desain.
Prinsip ini sebenarnya cukup dalam, karena itu berarti Anda harus melihat melampaui apa yang seharusnya dilakukan basis kode hari ini , dan juga mempertimbangkan kekuatan eksternal yang dapat menyebabkannya berubah, dan bahkan memahami berbagai pemangku kepentingan di belakang persyaratan.
sumber
Kedua jawaban saat ini tampaknya hanya mencapai sasaran, dan mereka berfokus pada contoh yang mengaburkan gagasan inti. Ini juga bukan (semata-mata) prinsip OOP tetapi prinsip desain perangkat lunak secara umum.
Hal yang "bervariasi" dalam frasa ini adalah kode. Christophe benar dalam mengatakan bahwa biasanya sesuatu yang mungkin berbeda, itulah yang sering Anda antisipasi . Tujuannya adalah melindungi diri Anda dari perubahan kode di masa mendatang. Ini terkait erat dengan pemrograman terhadap suatu antarmuka . Namun, Christophe salah untuk membatasi ini pada "detail implementasi". Bahkan, nilai nasihat ini sering kali disebabkan oleh perubahan persyaratan .
Ini hanya secara tidak langsung terkait dengan keadaan enkapsulasi, yang saya yakini sedang dipikirkan oleh David Arno. Nasihat ini tidak selalu (tetapi sering) menyarankan keadaan enkapsulasi, dan saran ini juga berlaku untuk objek yang tidak dapat diubah. Faktanya, konstanta penamaan hanyalah bentuk (sangat dasar) dari enkapsulasi yang bervariasi.
CandiedOrange secara eksplisit mengonfigurasi "apa yang bervariasi" dengan "perincian". Ini hanya sebagian benar. Saya setuju bahwa kode apa pun yang bervariasi adalah "perincian" dalam arti tertentu, tetapi "perincian" mungkin tidak berbeda (kecuali jika Anda mendefinisikan "perincian" untuk membuat tautologis ini). Mungkin ada alasan untuk merangkum detail yang tidak beragam, tetapi diktum ini bukan satu. Secara kasar, jika Anda sangat yakin bahwa "anjing", "kucing", dan "bebek" akan menjadi satu-satunya jenis yang perlu Anda tangani, maka diktum ini tidak menyarankan Refactoring yang dilakukan CandiedOrange.
Contoh Casting CandiedOrange dalam konteks yang berbeda, anggap kita memiliki bahasa prosedural seperti C. Jika saya memiliki beberapa kode yang berisi:
Saya mungkin berharap sepotong kode ini akan berubah di masa depan. Saya dapat "merangkum" itu hanya dengan mendefinisikan prosedur baru:
dan menggunakan prosedur baru ini alih-alih blok kode (yaitu refactoring "metode ekstrak"). Pada titik ini menambahkan jenis "sapi" atau apa pun yang hanya perlu memperbarui
speak
prosedur. Tentu saja, dalam bahasa OO Anda dapat memanfaatkan pengiriman dinamis seperti disinggung oleh jawaban CandiedOrange. Ini akan terjadi secara alami jika Anda mengaksespet
melalui antarmuka. Menghilangkan logika kondisional melalui pengiriman dinamis adalah masalah ortogonal yang merupakan bagian dari mengapa saya membuat tafsiran prosedural ini. Saya juga ingin menekankan bahwa ini tidak memerlukan fitur khusus untuk OOP. Bahkan dalam bahasa OO, merangkum apa yang bervariasi tidak berarti kelas atau antarmuka baru perlu dibuat.Sebagai contoh yang lebih tipikal (yang lebih dekat tetapi tidak cukup OO), katakanlah kami ingin menghapus duplikat dari daftar. Katakanlah kita menerapkannya dengan mengulangi daftar pencatatan item yang telah kita lihat sejauh ini di daftar lain dan menghapus item yang telah kita lihat. Masuk akal untuk berasumsi bahwa kami mungkin ingin mengubah cara kami melacak item yang dilihat mungkin, setidaknya, untuk alasan kinerja. Diktum untuk merangkum apa yang bervariasi menunjukkan bahwa kita harus membangun tipe data abstrak untuk mewakili set item yang terlihat. Algoritme kami sekarang ditentukan berdasarkan tipe data Set abstrak ini, dan jika kami memutuskan untuk beralih ke pohon pencarian biner, algoritma kami tidak perlu diubah atau dirawat. Dalam bahasa OO, kami dapat menggunakan kelas atau antarmuka untuk menangkap tipe data abstrak ini. Dalam bahasa seperti SML / O '
Untuk contoh yang didorong oleh persyaratan, misalkan Anda perlu memvalidasi beberapa bidang terkait dengan beberapa logika bisnis. Meskipun Anda mungkin memiliki persyaratan khusus sekarang, Anda sangat curiga bahwa mereka akan berkembang. Anda dapat merangkum logika saat ini dalam prosedur / fungsi / aturan / kelasnya sendiri.
Meskipun ini adalah masalah ortogonal yang bukan bagian dari "merangkum apa yang bervariasi", sering alami untuk abstrak, yang diparameterisasi oleh, logika yang sekarang dienkapsulasi. Ini biasanya mengarah pada kode yang lebih fleksibel dan memungkinkan logika diubah dengan mengganti dalam implementasi alternatif daripada memodifikasi logika yang dienkapsulasi.
sumber
"Enkapsulasi apa yang bervariasi" mengacu pada menyembunyikan detail implementasi yang dapat berubah dan berkembang.
Contoh:
Sebagai contoh, misalkan kelas
Course
melacakStudents
yang dapat mendaftar () Anda bisa menerapkannya denganLinkedList
dan mengekspos wadah untuk memungkinkan iterasi di atasnya:Tapi ini bukan ide yang baik:
Jika Anda merangkum apa yang bervariasi (atau lebih tepatnya mengatakan, apa yang mungkin berbeda), Anda tetap memiliki kebebasan untuk menggunakan kode dan kelas yang dienkapsulasi untuk berevolusi satu sama lain sendiri. Inilah sebabnya mengapa ini merupakan prinsip penting dalam OOP.
Bacaan tambahan:
sumber