Pertimbangkan dua kelas Dog
dan Cat
keduanya sesuai dengan Animal
protokol (dalam hal bahasa pemrograman Swift. Itu akan menjadi antarmuka dalam Java / C #).
Kami memiliki layar yang menampilkan daftar campuran anjing dan kucing. Ada Interactor
kelas yang menangani logika di balik layar.
Sekarang kami ingin menyajikan peringatan konfirmasi kepada pengguna ketika ia ingin menghapus kucing. Namun, anjing harus segera dihapus tanpa pemberitahuan. Metode dengan kondisional akan terlihat seperti ini:
func tryToDeleteModel(model: Animal) {
if let model = model as? Cat {
tellSceneToShowConfirmationAlert()
} else if let model = model as? Dog {
deleteModel(model: model)
}
}
Bagaimana kode ini dapat di refactored? Jelas baunya
sumber
Dog
danCat
digambarkan sebagai kelas, sedangkanAnimal
protokol yang diterapkan oleh masing-masing kelas tersebut. Jadi ada sedikit ketidakcocokan antara pertanyaan dan jawaban Anda.Interactor
kondisi sekarangCat
danDog
ditangani, itu bisa dan harus menjadi properti umum diAnimal
. Melakukan hal lain adalah meminta perawatan sakit kepala nanti.Tell vs. Ask
Pendekatan bersyarat yang Anda tunjukkan akan kami sebut " bertanya ". Di sinilah klien yang mengkonsumsi bertanya "kamu seperti apa?" dan menyesuaikan perilaku dan interaksi mereka dengan objek sesuai.
Ini kontras dengan alternatif yang kita sebut " kirim ". Dengan menggunakan tell , Anda mendorong lebih banyak pekerjaan ke dalam implementasi polimorfik, sehingga kode klien yang digunakan lebih sederhana, tanpa persyaratan, dan umum terlepas dari kemungkinan implementasi.
Karena Anda ingin menggunakan lansiran konfirmasi, Anda bisa menjadikannya kemampuan antarmuka yang eksplisit. Jadi, Anda mungkin memiliki metode boolean yang secara opsional memeriksa dengan pengguna dan mengembalikan boolean konfirmasi. Di kelas yang tidak ingin mengkonfirmasi, mereka hanya menimpanya
return true;
. Implementasi lain mungkin secara dinamis menentukan apakah mereka ingin menggunakan konfirmasi.Klien yang mengkonsumsi akan selalu menggunakan metode konfirmasi terlepas dari subkelas tertentu yang bekerja sama dengannya, yang membuat interaksi mengatakan daripada meminta .
(Pendekatan lain adalah dengan mendorong konfirmasi ke penghapusan, tetapi itu akan mengejutkan klien yang mengharapkan operasi penghapusan untuk berhasil.)
sumber
Interactor
keadaan sekarangMenentukan apakah konfirmasi diperlukan adalah tanggung jawab
Cat
kelas, jadi aktifkan untuk melakukan tindakan itu. Saya tidak tahu Kotlin, jadi saya akan mengungkapkan hal-hal dalam C #. Semoga ide-ide tersebut kemudian dapat ditransfer ke Kotlin juga.Kemudian, saat membuat sebuah
Cat
instance, Anda menyediakannyaTellSceneToShowConfirmationAlert
, yang harus dikembalikantrue
jika OK untuk menghapus:Dan kemudian fungsi Anda menjadi:
sumber
Cat
kelas. Saya berpendapat bahwa itu adalah tempatnya. Itu tidak bisa memutuskan bagaimana konfirmasi itu dicapai (yang disuntikkan) dan itu tidak menghapus sendiri. Jadi tidak, itu tidak memindahkan logika delete ke dalam model.TellSceneToShowConfirmationAlert
ke instanceCat
. Dalam situasi di mana itu bukan hal yang mudah (seperti dalam sistem multi-layered di mana fungsi ini terletak pada level yang dalam), maka pendekatan ini tidak akan menjadi yang baik.Saya akan menyarankan untuk pergi untuk pola Pengunjung. Saya melakukan implementasi kecil di Jawa. Saya tidak terbiasa dengan Swift, tetapi Anda dapat mengadaptasinya dengan mudah.
Pengunjung
Model Anda
Memanggil pengunjung
Anda dapat memiliki implementasi AnimalVisitor sebanyak yang Anda inginkan.
Contoh:
sumber