Pertama mari kita perjelas paradigma.
- Struktur Data -> tata letak memori yang dapat dilalui dan dimanipulasi oleh fungsi yang sesuai dengan pengetahuan.
- Objek -> modul mandiri yang menyembunyikan implementasinya dan menyediakan antarmuka yang dapat dikomunikasikan.
Di mana pengambil / penyetel berguna?
Apakah getter / setter berguna dalam Struktur Data? Tidak.
Struktur Data adalah spesifikasi tata letak memori yang umum dan dimanipulasi oleh sekumpulan fungsi.
Secara umum, setiap fungsi baru yang lama dapat muncul dan memanipulasi struktur data, jika ia melakukannya sedemikian rupa sehingga fungsi lainnya masih dapat memahaminya, maka fungsi tersebut bergabung dengan keluarga. Kalau tidak, ini adalah fungsi jahat dan sumber bug.
Jangan salah paham, mungkin ada beberapa keluarga fungsi yang berperang karena struktur data dengan snitch, turn-coats, dan agen ganda di mana-mana. Tidak apa-apa ketika mereka masing-masing memiliki struktur data sendiri untuk dimainkan, tetapi ketika mereka membagikannya ... bayangkan saja beberapa keluarga kriminal yang tidak setuju dengan politik, itu bisa menjadi kekacauan yang sangat cepat.
Mengingat kekacauan yang dapat dicapai fungsi keluarga, apakah ada cara untuk menyandikan struktur data sehingga fungsi jahat tidak mengacaukan semuanya? Ya, mereka disebut Objects.
Apakah getter / setter berguna di Objek? Tidak.
Inti dari membungkus struktur data di suatu objek adalah untuk memastikan bahwa tidak ada fungsi jahat yang bisa ada. Jika fungsi ingin bergabung dengan keluarga, itu harus diperiksa terlebih dahulu dan kemudian menjadi bagian dari objek.
Titik / tujuan pengambil dan penyetel adalah untuk memungkinkan fungsi di luar objek untuk mengubah tata letak memori objek secara langsung. Kedengarannya seperti pintu terbuka untuk mengizinkan penyamun ...
Kasus Tepi
Ada dua situasi ketika seorang pengambil / pembuat keputusan masuk akal.
- Sebagian dari struktur data dalam objek dikelola oleh objek, tetapi tidak dikendalikan oleh objek.
- Antarmuka yang menggambarkan abstraksi tingkat tinggi dari struktur data di mana beberapa elemen diharapkan tidak dapat mengendalikan objek pelaksana.
Kontainer dan antarmuka wadah adalah contoh sempurna dari kedua situasi ini. Kontainer mengelola struktur data (daftar terkait, peta, pohon) secara internal tetapi dengan mudah mengendalikan elemen tertentu untuk semuanya. Antarmuka mengabstraksi hal ini dan mengabaikan implementasi sepenuhnya dan hanya menggambarkan harapan.
Sayangnya banyak implementasi yang salah dan mendefinisikan antarmuka objek semacam ini untuk memberikan akses langsung ke objek yang sebenarnya. Sesuatu seperti:
interface Container<T>
{
typedef ...T... TRef; //<somehow make TRef to be a reference or pointer to the memory location of T
TRef item(int index);
}
Ini rusak Implementasi Container harus secara eksplisit menyerahkan kontrol internal mereka kepada siapa pun yang menggunakannya. Saya belum melihat bahasa dengan nilai yang bisa berubah-ubah di mana ini baik-baik saja (bahasa dengan semantik bernilai tidak berubah secara definisi baik dari perspektif korupsi data, tetapi tidak harus dari perspektif mata-mata data).
Anda dapat meningkatkan / memperbaiki getter / setter dengan hanya menggunakan copy-semantik, atau dengan menggunakan proxy:
interface Proxy<T>
{
operator T(); //<returns a copy
... operator ->(); //<permits a function call to be forwarded to an element
Proxy<T> operator=(T); //< permits the specific element to be replaced/assigned by another T.
}
interface Container<T>
{
Proxy<T> item(int index);
T item(int index); //<When T is a copy of the original value.
void item(int index, T new_value); //<where new_value is used to replace the old value
}
Bisa dibilang fungsi jahat masih bisa memainkan kekacauan di sini (dengan upaya yang cukup banyak hal yang mungkin), tetapi copy-semantik dan / atau proksi mengurangi kemungkinan sejumlah kesalahan.
- meluap
- underflow
- interaksi dengan sub elemen adalah tipe-checked / type-checkable (dalam bahasa tipe hilang ini adalah anugerah)
- Elemen aktual mungkin atau mungkin bukan memori.
Setter Pribadi / Setter
Ini adalah benteng getter dan setter terakhir yang bekerja pada tipe ini secara langsung. Sebenarnya saya bahkan tidak akan memanggil getter dan setter ini selain accessor dan manipulator.
Dalam konteks ini kadang-kadang memanipulasi bagian tertentu dari struktur data selalu / hampir selalu / umumnya membutuhkan pembukuan khusus untuk terjadi. Katakanlah ketika Anda memperbarui root dari pohon cache yang perlu disingkirkan harus dibersihkan, atau ketika Anda mengakses elemen data eksternal, kunci perlu diperoleh / dirilis. Dalam kasus ini masuk akal untuk menerapkan prinsip KERING dan membagi tindakan tersebut bersama-sama.
Dalam konteks pribadi, masih mungkin bagi fungsi-fungsi lain dalam keluarga untuk mengesampingkan 'getter dan setter' ini dan memanipulasi struktur data. Karena itu mengapa saya menganggap mereka lebih sebagai penentu dan manipulator. Anda dapat mengakses data secara langsung, atau mengandalkan anggota keluarga lain untuk mendapatkan bagian itu dengan benar.
Getters / Setters yang dilindungi
Dalam konteks yang dilindungi, tidak jauh berbeda dengan konteks publik. Fungsi asing yang mungkin ingin akses ke struktur data. Jadi tidak, jika mereka ada mereka beroperasi seperti pengambil / setter publik.
this->variable = x + 5
, atau memanggilUpdateStatistics
fungsi dalam setter, dan dalam kasus-kasus ituclassinstancea->variable = 5
akan menyebabkan masalah.