Di Jawa secara khusus, tetapi kemungkinan dalam bahasa lain juga: kapan akan berguna untuk memiliki dua referensi ke objek yang sama?
Contoh:
Dog a = new Dog();
Dob b = a;
Apakah ada situasi di mana ini akan bermanfaat? Mengapa ini menjadi solusi yang lebih disukai untuk digunakan a
kapan pun Anda ingin berinteraksi dengan objek yang diwakili a
?
object-oriented
object-oriented-design
object
Bassinator
sumber
sumber
a
danb
selalu merujuk hal yang samaDog
, maka tidak ada gunanya. Jika mereka kadang - kadang mungkin, maka itu sangat berguna.Jawaban:
Contohnya adalah ketika Anda ingin memiliki objek yang sama dalam dua daftar terpisah :
Penggunaan lain adalah ketika Anda memiliki objek yang sama memainkan beberapa peran :
sumber
Persona batman = new Persona("Batman"); Persona bruce = new Persona("Bruce Wayne"); Persona currentPersona = batman;
- di mana Anda memiliki beberapa nilai yang mungkin (atau daftar nilai yang tersedia) dan referensi ke yang saat ini aktif / dipilih.currentPersona
menunjuk ke satu objek atau yang lain, tetapi tidak pernah keduanya. Secara khusus, mungkin dengan mudah mungkin bahwacurrentPersona
ini tidak pernah diatur untukbruce
, dalam hal itu jelas tidak referensi ke dua objek. Saya akan mengatakan itu, dalam contoh saya, keduanyabatman
dancurrentPersona
merupakan referensi untuk contoh yang sama, tetapi melayani makna semantik yang berbeda dalam program.Itu sebenarnya pertanyaan yang sangat mengejutkan! Pengalaman dari C ++ modern (dan bahasa yang mengambil dari C ++ modern, seperti Rust) menunjukkan bahwa sangat sering, Anda tidak menginginkan itu! Untuk sebagian besar data, Anda ingin referensi tunggal atau unik ("memiliki"). Ide ini juga merupakan satu alasan utama untuk sistem tipe linear .
Namun, meskipun demikian Anda biasanya menginginkan beberapa referensi "pinjaman" berumur pendek yang digunakan untuk mengakses memori secara singkat tetapi tidak bertahan untuk sebagian kecil dari waktu data itu ada. Paling umum ketika Anda melewatkan objek sebagai argumen ke fungsi yang berbeda (Parameter juga variabel!):
Kasus yang kurang umum ketika Anda menggunakan salah satu dari dua objek tergantung pada suatu kondisi, pada dasarnya melakukan hal yang sama terlepas dari apa yang Anda pilih:
Kembali ke penggunaan yang lebih umum, tetapi meninggalkan variabel lokal, kita beralih ke bidang: Misalnya, widget dalam kerangka GUI sering memiliki widget induk, sehingga kerangka besar Anda yang berisi sepuluh tombol akan memiliki setidaknya sepuluh referensi yang menunjuk padanya (ditambah beberapa lagi dari yang tua dan mungkin dari pendengar acara dan sebagainya). Setiap jenis objek grafik, dan beberapa jenis pohon objek (yang memiliki referensi induk / saudara kandung), memiliki beberapa objek merujuk ke masing-masing objek yang sama. Dan sebenarnya setiap set data sebenarnya adalah grafik ;-)
sumber
Variabel sementara: pertimbangkan kodesemu berikut.
Variabel
max
dancandidate
mungkin menunjuk ke objek yang sama, tetapi penugasan variabel berubah menggunakan aturan yang berbeda dan pada waktu yang berbeda.sumber
Untuk melengkapi jawaban lain, Anda mungkin juga ingin melintasi struktur data secara berbeda, mulai dari tempat yang sama. Misalnya, jika Anda memiliki
BinaryTree a = new BinaryTree(...); BinaryTree b = a
, Anda dapat melintasi jalan paling kiri pohon dengana
dan jalan paling kanan dengannyab
, menggunakan sesuatu seperti:Sudah lama sejak saya menulis Java, sehingga kode itu mungkin tidak benar atau masuk akal. Ambillah lebih sebagai pseudocode.
sumber
Metode ini sangat bagus ketika Anda memiliki beberapa objek yang semuanya memanggil kembali ke objek lain yang dapat digunakan secara tidak kontekstual.
Misalnya, jika Anda memiliki antarmuka tab Anda mungkin memiliki Tab1, Tab2, dan Tab3. Anda juga mungkin ingin dapat menggunakan variabel umum terlepas dari tab mana pengguna aktif untuk menyederhanakan kode Anda dan mengurangi harus mencari tahu dengan cepat di mana tab pengguna Anda berada.
Lalu, di masing-masing tab bernomor diKlik, Anda bisa mengubah CurrentTab untuk referensi Tab itu.
Sekarang dalam kode Anda, Anda dapat memanggil "CurrentTab" dengan bebas dari hukuman tanpa perlu tahu di mana Anda sebenarnya berada. Anda juga dapat memperbarui properti CurrentTab dan secara otomatis akan mengalir ke Tab yang direferensikan.
sumber
Ada banyak skenario di mana
b
harus ada referensi ke "a
" yang tidak diketahui agar bermanfaat. Khususnya:b
menunjuk pada saat kompilasi.Sebagai contoh:
Parameter
t
adalah referensi ke variabel dari lingkup luar.Mengembalikan nilai dan nilai kondisional lainnya
biggerThing
danz
masing-masing referensi untuk salah satua
ataub
. Kami tidak tahu yang mana pada saat kompilasi.Lambdas dan nilai kembalinya mereka
x
adalah parameter (contoh 1 di atas), dant
merupakan nilai balik (contoh 2 di atas)Koleksi
index["some name"]
adalah, sebagian besar, tampak lebih canggihb
. Ini adalah alias untuk objek yang dibuat dan dimasukkan ke dalam koleksi.Loop
t
adalah referensi ke item yang dikembalikan (contoh 2) oleh iterator (contoh sebelumnya).sumber
Ini adalah poin penting, tapi IMHO patut dipahami.
Semua bahasa OO selalu membuat salinan referensi, dan tidak pernah menyalin objek 'tidak terlihat'. Akan jauh lebih sulit untuk menulis program jika bahasa OO bekerja dengan cara lain. Misalnya, fungsi, dan metode, tidak pernah dapat memperbarui objek. Java, dan sebagian besar bahasa OO hampir tidak mungkin digunakan tanpa kompleksitas tambahan yang signifikan.
Objek dalam suatu program seharusnya memiliki arti. Misalnya itu mewakili sesuatu yang spesifik di dunia fisik nyata. Biasanya masuk akal jika memiliki banyak referensi untuk hal yang sama. Misalnya, alamat rumah saya dapat diberikan kepada banyak orang dan organisasi, dan alamat itu selalu merujuk ke lokasi fisik yang sama. Jadi poin pertama adalah, obyek sering mewakili sesuatu yang spesifik, nyata, atau konkret; sehingga dapat memiliki banyak referensi untuk hal yang sama sangat berguna. Kalau tidak, akan lebih sulit untuk menulis program.
Setiap kali Anda meneruskan
a
sebagai argumen / parameter ke fungsi lain misalnya memanggilfoo(Dog aDoggy);
atau menerapkan metode
a
, kode program yang mendasari membuat salinan referensi, untuk menghasilkan referensi kedua ke objek yang sama.Lebih lanjut, jika kode dengan referensi yang disalin berada di utas yang berbeda, maka keduanya dapat digunakan secara bersamaan untuk mengakses objek yang sama.
Jadi dalam sebagian besar program yang bermanfaat, akan ada banyak referensi ke objek yang sama, karena itu adalah semantik dari sebagian besar bahasa pemrograman OO.
Sekarang, jika kita memikirkannya, karena lewat referensi adalah satu - satunya mekanisme yang tersedia dalam banyak bahasa OO (C ++ mendukung keduanya), kita mungkin berharap itu menjadi perilaku default 'benar' .
IMHO, menggunakan referensi adalah default yang tepat , karena beberapa alasan:
Ada juga argumen efisiensi; membuat salinan seluruh objek kurang efisien daripada menyalin referensi. Namun, saya pikir itu melenceng. Berbagai referensi ke objek yang sama lebih masuk akal, dan lebih mudah digunakan, karena cocok dengan semantik dunia fisik nyata.
Jadi, IMHO, biasanya masuk akal untuk memiliki banyak referensi ke objek yang sama. Dalam kasus yang tidak biasa di mana itu tidak masuk akal dalam konteks suatu algoritma, sebagian besar bahasa menyediakan kemampuan untuk membuat 'klon' atau salinan dalam. Namun itu bukan default.
Saya pikir orang-orang yang berpendapat bahwa ini seharusnya bukan default menggunakan bahasa yang tidak menyediakan pengumpulan sampah otomatis. Misalnya, C ++ kuno. Masalahnya adalah bahwa mereka perlu menemukan cara untuk mengumpulkan benda-benda 'mati' dan tidak mengklaim kembali benda-benda yang mungkin masih diperlukan; memiliki banyak referensi ke objek yang sama menjadikannya sulit.
Saya pikir, jika C ++ memiliki pengumpulan sampah yang cukup murah, sehingga semua objek yang direferensikan adalah sampah yang dikumpulkan, maka sebagian besar keberatan hilang. Masih ada beberapa kasus di mana semantik referensi tidak dibutuhkan. Namun, dalam pengalaman saya, orang-orang yang dapat mengidentifikasi situasi-situasi itu juga biasanya mampu memilih semantik yang sesuai pula.
Saya percaya ada beberapa bukti bahwa sejumlah besar kode dalam program C ++ ada untuk menangani atau mengurangi pengumpulan sampah. Namun, menulis, dan memelihara kode 'infrastruktur' semacam itu menambah biaya; itu ada untuk membuat bahasa lebih mudah digunakan, atau lebih kuat. Jadi, misalnya bahasa Go dirancang dengan fokus untuk memulihkan beberapa kelemahan C ++, dan tidak memiliki pilihan selain pengumpulan sampah.
Ini tentu saja tidak relevan dalam konteks Jawa. Itu juga dirancang agar mudah digunakan, dan begitu pula pengumpulan sampah. Oleh karena itu memiliki banyak referensi adalah semantik default, dan relatif aman dalam arti bahwa objek tidak direklamasi sementara ada referensi ke sana. Tentu saja mereka mungkin dipegang oleh struktur data karena program tidak benar merapikan ketika sudah benar-benar selesai dengan objek.
Jadi, berputar kembali ke pertanyaan Anda (dengan sedikit generalisasi), kapan Anda ingin lebih dari satu referensi ke objek yang sama? Cukup banyak dalam setiap situasi yang dapat saya pikirkan. Mereka adalah semantik default dari sebagian besar mekanisme parameter lewat bahasa. Saya menyarankan itu karena semantik default untuk menangani objek yang ada di dunia nyata cukup banyak dengan referensi ('karena objek yang sebenarnya ada di luar sana).
Semantik lainnya akan lebih sulit ditangani.
Saya menyarankan bahwa "bajak" di
dl
harus yang dipengaruhi olehsetOwner
atau program menjadi sulit untuk menulis, memahami, men-debug atau memodifikasi. Saya pikir sebagian besar programmer akan bingung atau kecewa sebaliknya.kemudian, anjing itu dijual:
Jenis pemrosesan ini biasa dan normal. Jadi referensi semantik adalah default karena biasanya paling masuk akal.
Ringkasan: Selalu masuk akal untuk memiliki banyak referensi ke objek yang sama.
sumber
Tentu saja, satu skenario lain di mana Anda mungkin berakhir dengan:
adalah ketika Anda memelihara kode dan
b
digunakan untuk menjadi anjing yang berbeda, atau kelas yang berbeda, tetapi sekarang dilayani oleha
.Secara umum, dalam jangka menengah, Anda harus mengolah kembali semua kode untuk merujuk
a
langsung, tetapi itu mungkin tidak langsung terjadi.sumber
Anda ingin ini kapan saja program Anda memiliki peluang menarik entitas ke dalam memori di lebih dari satu tempat, mungkin karena berbagai komponen menggunakannya.
Identity Maps menyediakan penyimpanan entitas lokal yang pasti sehingga kami dapat menghindari memiliki dua atau lebih representasi terpisah. Saat kami merepresentasikan objek yang sama dua kali, klien kami berisiko menyebabkan masalah konkurensi jika satu referensi objek bertahan keadaannya berubah sebelum instance lain lainnya melakukannya. Idenya adalah kami ingin memastikan bahwa klien kami selalu memberikan referensi definitif ke entitas / objek kami.
sumber
Saya menggunakan ini saat menulis pemecah Sudoku. Ketika saya tahu jumlah sel saat memproses baris, saya ingin kolom yang berisi untuk mengetahui nomor sel juga saat memproses kolom. Jadi baik kolom dan baris adalah array objek Cell yang tumpang tindih. Persis seperti yang ditunjukkan jawaban yang diterima.
sumber
Dalam aplikasi web, Pemetaan Objek Relasional dapat menggunakan pemuatan malas sehingga semua referensi ke objek basis data yang sama (setidaknya dalam utas yang sama) menunjuk ke hal yang sama.
Misalnya, jika Anda memiliki dua tabel:
Anjing:
Pemilik:
Ada beberapa pendekatan yang dapat dilakukan ORM Anda jika panggilan berikut dilakukan:
Dalam strategi naif, semua panggilan ke model dan referensi terkait mengambil objek yang terpisah.
Dog.find()
,Owner.find()
,owner.dogs
, Dandog.owner
hasilnya dalam database hit pertama kali sekitar, setelah itu mereka akan disimpan ke memori. Dan sebagainya:Tanpa referensi, Anda memiliki lebih banyak pengambilan, menggunakan lebih banyak memori, dan memperkenalkan kemungkinan menimpa pembaruan sebelumnya.
Misalkan ORM Anda tahu bahwa semua referensi ke baris 1 dari tabel dogs harus mengarah ke hal yang sama. Kemudian:
Dengan kata lain, menggunakan referensi membantu mengkodifikasi prinsip satu titik kebenaran (setidaknya dalam utas itu) menjadi baris dalam database.
sumber