Kapan pun saya bisa, saya mencoba membatasi komunikasi antara objek ke model permintaan dan respons. Ada urutan parsial tersirat pada objek dalam program saya sehingga antara dua objek A dan B, mungkin ada cara bagi A untuk secara langsung atau tidak langsung memanggil metode B atau untuk B untuk secara langsung atau tidak langsung memanggil metode A , tetapi tidak pernah mungkin bagi A dan B untuk saling memanggil metode satu sama lain. Terkadang, tentu saja, Anda ingin memiliki komunikasi mundur dengan penelepon suatu metode. Ada beberapa cara yang saya suka lakukan ini, dan tidak satu pun dari mereka adalah panggilan balik.
Salah satu caranya adalah dengan memasukkan lebih banyak informasi dalam nilai balik dari pemanggilan metode, yang berarti kode klien dapat memutuskan apa yang harus dilakukan dengannya setelah prosedur mengembalikan kontrol ke sana.
Cara lain adalah dengan memanggil objek anak bersama. Yaitu, jika A memanggil metode pada B, dan B perlu mengkomunikasikan beberapa informasi ke A, B memanggil metode pada C, di mana A dan B keduanya dapat memanggil C, tetapi C tidak dapat memanggil A atau B. Objek A akan menjadi bertanggung jawab untuk mendapatkan informasi dari C setelah B mengembalikan kontrol ke A. Perhatikan bahwa ini sebenarnya tidak jauh berbeda dari cara pertama yang saya usulkan. Objek A masih dapat hanya mengambil informasi dari nilai kembali; tidak ada metode objek A yang dipanggil oleh B atau C. Variasi trik ini adalah untuk lulus C sebagai parameter untuk metode, tetapi pembatasan pada hubungan C ke A dan B masih berlaku.
Sekarang, pertanyaan penting adalah mengapa saya bersikeras melakukan hal-hal seperti ini. Ada tiga alasan utama:
- Itu membuat benda-benda saya lebih longgar digabungkan. Objek saya mungkin merangkum objek lain, tetapi mereka tidak akan pernah bergantung pada konteks pemanggil, dan konteks tidak akan pernah bergantung pada objek yang dienkapsulasi.
- Itu membuat aliran kendali saya mudah dipikirkan. Sangat menyenangkan untuk dapat mengasumsikan bahwa satu-satunya kode yang dapat mengubah keadaan internal
self
sementara metode mengeksekusi adalah satu metode dan tidak ada yang lain. Ini adalah jenis pemikiran yang sama yang mungkin menyebabkan seseorang untuk menempatkan mutex pada objek bersamaan.
- Ini melindungi invarian pada data enkapsulasi objek saya. Metode publik diizinkan untuk bergantung pada invarian, dan invarian tersebut dapat dilanggar jika satu metode dapat dipanggil secara eksternal sementara metode lain sudah dijalankan.
Saya tidak menentang semua penggunaan callback. Sesuai dengan kebijakan saya tentang tidak pernah "memanggil penelepon," jika suatu objek A memanggil metode pada B dan meneruskan panggilan balik ke sana, panggilan balik tidak dapat mengubah keadaan internal A, dan itu termasuk objek yang dienkapsulasi oleh A dan objek dalam konteks A. Dengan kata lain, callback hanya dapat memanggil metode pada objek yang diberikan kepadanya oleh B. Callback, pada dasarnya, berada di bawah batasan yang sama dengan B.
Salah satu jalan keluar terakhir untuk mengikat adalah bahwa saya akan mengijinkan doa dari setiap fungsi murni, terlepas dari pemesanan parsial ini yang telah saya bicarakan. Fungsi murni sedikit berbeda dari metode yang tidak dapat diubah atau bergantung pada efek atau efek samping yang dapat berubah, sehingga tidak ada kekhawatiran tentang hal-hal yang membingungkan.