Saya telah mempelajari pemrograman OO, terutama di C ++, C # dan Java. Saya pikir saya memiliki pemahaman yang baik tentangnya dengan pemahaman saya tentang enkapsulasi, pewarisan dan polimorfisme (serta membaca banyak pertanyaan di situs ini).
Satu hal yang sepertinya muncul di sana-sini adalah konsep "message passing". Rupanya, ini adalah sesuatu yang tidak digunakan saat pemrograman OO dalam bahasa arus utama saat ini, tetapi didukung oleh Smalltalk.
Pertanyaan saya adalah:
- Apa yang lewat pesan? (Bisakah seseorang memberi contoh praktis?)
- Apakah ada dukungan untuk "passing pesan" ini dalam C ++, C # atau Java?
java
c#
c++
object-oriented
Tom
sumber
sumber
Jawaban:
Pesan yang lewat hanya berarti bahwa (pada tingkat yang sangat abstrak) mekanisme dasar pelaksanaan program adalah objek yang saling mengirim pesan. Poin penting adalah bahwa nama dan struktur pesan-pesan ini belum tentu diperbaiki sebelumnya dalam kode sumber dan itu sendiri dapat menjadi informasi tambahan. Ini adalah bagian penting dari apa yang Alan Kay awalnya bayangkan sebagai "pemrograman berorientasi objek".
Bahasa ini menerapkan versi terbatas pesan yang melewati panggilan metode. Terbatas karena set pesan yang dapat dikirim terbatas pada metode yang dideklarasikan di kelas. Keuntungan dari pendekatan ini adalah dapat diimplementasikan dengan sangat efisien, dan memungkinkan analisis kode statis yang sangat terperinci (yang menghasilkan semua jenis manfaat yang bermanfaat, seperti penyelesaian kode).
Sebaliknya, bahasa yang menerapkan kelulusan pesan "nyata" sering memiliki definisi metode juga, sebagai cara yang nyaman untuk mengimplementasikan penangan pesan, tetapi memungkinkan kelas untuk mengimplementasikan penangan pesan yang lebih fleksibel yang memungkinkan objek menerima "panggilan metode" dengan nama sewenang-wenang (tidak diperbaiki pada waktu kompilasi).
Sebuah contoh dalam Groovy yang menunjukkan kekuatan konsep ini:
akan menghasilkan XML ini:
Perhatikan bahwa
records
,car
,country
danrecord
sintaksis metode panggilan, tetapi tidak ada metode nama yang didefinisikan dalamMarkupBuilder
. Sebaliknya, ia memiliki penangan pesan catchall yang menerima semua pesan dan menafsirkan nama pesan sebagai nama elemen XML, parameter sebagai atribut dan penutupan sebagai elemen anak.sumber
sendMessage(property_name, Array of arguments)
dangetMessage(property_name, Array of arguments)
dalam bahasa statis?Pesan yang lewat adalah cara berbeda dalam menangani kebutuhan dalam kode OO untuk satu objek untuk mendapatkan objek lain (atau berpotensi sendiri) untuk melakukan sesuatu.
Dalam sebagian besar bahasa modern yang berasal dari pendekatan C ++ kami melakukannya dengan pemanggilan metode. Dalam hal ini objek yang dipanggil (melalui definisi kelasnya) menempatkan daftar besar apa yang diterima metode dan kemudian pembuat kode dari objek yang memanggil hanya menulis panggilan:
Untuk bahasa yang diketik secara statis maka kompiler kemudian dapat memeriksa jenis hal yang dipanggil dan mengonfirmasi bahwa metode telah dideklarasikan. Untuk bahasa yang diketik secara dinamis maka itu dilakukan pada saat runtime.
Tetapi pada dasarnya yang terjadi adalah bahwa kumpulan variabel dikirim ke blok kode tertentu.
Pesan lewat
Dalam bahasa lewat pesan (seperti Objective C) bukan metode ada penerima, tetapi secara luas pendekatan mendefinisikan mereka dan memanggil mereka hampir sama - perbedaannya adalah cara penanganannya.
Dalam pesan yang lewat bahasa, kompiler dapat memeriksa apakah penerima yang Anda panggil ada, tetapi paling buruk itu akan memunculkan peringatan untuk mengatakan bahwa tidak ada di sana. Ini karena pada saat run time yang akan terjadi adalah bahwa suatu blok kode pada objek penerima akan dipanggil lewat bundel variabel dan tanda tangan penerima yang ingin Anda panggil. Blok kode itu kemudian mencari penerima dan memanggilnya. Namun jika penerima tidak ada maka kode hanya akan mengembalikan nilai default.
Akibatnya salah satu keanehan yang ditemukan ketika pindah dari C ++ / Java -> Objective C adalah memahami bahwa Anda dapat "memanggil metode" pada objek yang tidak dideklarasikan pada tipe waktu kompilasi, dan bahkan tidak ada pada jenis run-time ... dan bahwa panggilan tidak akan menghasilkan pengecualian yang dilemparkan tetapi pada kenyataannya hasil yang dikembalikan.
Keuntungan dari pendekatan ini adalah bahwa hal itu meratakan hirarki subclass dan menghindari sebagian besar kebutuhan untuk antarmuka / beberapa jenis warisan / bebek. Ini juga memungkinkan objek untuk mendefinisikan perilaku default ketika diminta untuk melakukan sesuatu yang mereka tidak punya penerima (biasanya "jika saya tidak melakukannya, teruskan permintaan ke objek lain ini"). Itu juga dapat menyederhanakan penautan ke callback (misalnya untuk elemen UI dan peristiwa dengan waktu tertentu) terutama pada bahasa yang diketik secara statis seperti Java (sehingga Anda dapat meminta tombol memanggil penerima "runTest" daripada memanggil metode "actionPerformed" pada kelas dalam) "RunTestButtonListener" yang melakukan panggilan untuk Anda).
Namun tampaknya akan menjadi biaya dari kebutuhan untuk pemeriksaan tambahan oleh pengembang bahwa panggilan yang mereka pikir mereka lakukan adalah pada objek yang tepat dengan tipe yang tepat dan melewati parameter yang tepat dalam urutan yang benar, karena kompiler mungkin tidak memperingatkan Anda dan itu akan berjalan dengan baik saat runtime (hanya mengembalikan respons default). Ada juga bisa dibilang hit kinerja dari pencarian ekstra dan melewati paramter.
Saat ini, bahasa yang diketik secara dinamis dapat memberikan banyak manfaat dari pesan yang lulus OO dengan lebih sedikit masalah.
sumber
Arsitektur passing pesan hanyalah sistem di mana setiap komponen tidak tergantung pada yang lain, dengan mekanisme umum untuk mengirimkan data di antara mereka. Anda dapat mempertimbangkan pemanggilan metode sebagai bentuk pengiriman pesan, tetapi tidak praktis untuk melakukannya - ini membingungkan masalah. Ini karena jika Anda memiliki kelas dengan metode yang terdefinisi dengan baik, dan beberapa kode yang memanggil metode tersebut, keseluruhannya harus dikompilasi bersama, sehingga menyatukan kode dan objek. Anda dapat melihat seberapa dekat (saat pesan dikirimkan, dan kompiler menegakkan kebenaran, tetapi ia kehilangan banyak fleksibilitas dari sistem yang dipisahkan).
Arsitektur lewat pesan sering memungkinkan objek untuk ditambahkan saat runtime, dan lebih sering daripada tidak memungkinkan pesan untuk diarahkan ke satu atau lebih objek. Jadi saya dapat memiliki beberapa kode yang menyiarkan pesan 'data x diperbarui' ke semua objek yang telah dimuat ke dalam sistem, dan masing-masing dari mereka dapat mengambil tindakan apa pun yang mereka suka dengan informasi itu.
Contoh aneh adalah web. HTTP adalah sistem penyampaian pesan - Anda melewatkan kata kerja perintah dan 'paket data' ke proses server. (mis. DAPATKAN http: \ myserver \ url) Baik browser Anda, maupun server web tidak peduli apa pun tentang data yang Anda kirim, atau ke mana Anda mengirimnya. Server akan meneruskannya ke kode yang akan mengemas 'paket' data lain dan mengirimkannya kembali kepada Anda. Tidak ada komponen dalam sistem ini yang tahu apa-apa tentang pekerjaan orang lain atau apa yang mereka lakukan, mereka hanya tahu protokol yang digunakan untuk komunikasi pesan.
sumber