Dalam video ini oleh Rich Hickey , pencipta Clojure, ia menyarankan untuk menggunakan peta untuk mewakili data alih-alih menggunakan kelas untuk mewakilinya, seperti yang dilakukan di Jawa. Saya tidak mengerti bagaimana ini bisa lebih baik, karena bagaimana pengguna API dapat mengetahui apa kunci input jika mereka hanya direpresentasikan sebagai peta.
Contoh :
PersonAPI {
Person addPerson(Person obj);
Map<String, Object> addPerson(Map<String, Object> personMap);
}
Dalam fungsi kedua bagaimana pengguna API dapat mengetahui apa saja input untuk membuat seseorang?
Jawaban:
Ringkasan Eksaggitif (TM)
Anda mendapatkan beberapa hal.
Ada satu kelemahan fatal.
Masalahnya, Anda bisa mendapatkan introspeksi dengan menggunakan, um, introspeksi. Inilah yang biasanya terjadi:
Dengan kata lain, jika Anda tidak perlu berinteraksi dengan FP, Anda tidak harus mengikuti saran Rich Hickey.
Terakhir, tetapi tidak sedikit (atau paling cantik), meskipun menggunakan
String
sebagai kunci properti masuk akal, Anda tidak harus menggunakanString
s. Banyak sistem lama, termasuk Android ™, menggunakan ID integer secara ekstensif melalui seluruh kerangka kerja untuk merujuk ke kelas, properti, sumber daya, dll.Android adalah merek dagang dari Google Inc.
Anda juga bisa membuat kedua dunia bahagia.
Untuk dunia Jawa, terapkan getter dan setter seperti biasa.
Untuk dunia FP, terapkan
Object getPropertyByName(String name)
void setPropertyByName(String name, Object value) throws IllegalPropertyChangeException
List<String> getPropertyNames()
Class<?> getPropertyValueClass(String name)
Di dalam fungsi ini, ya, kode jelek, tetapi ada plugin IDE yang akan mengisinya untuk Anda, menggunakan ... eh, plugin pintar yang membaca kode Anda.
Sisi Jawa hal-hal akan sama seperti pemain seperti biasa. Mereka tidak akan pernah menggunakan bagian kode yang jelek itu . Anda bahkan mungkin ingin menyembunyikannya dari Javadoc.
Sisi FP dunia dapat menulis kode "leet" apa pun yang mereka inginkan, dan mereka biasanya tidak meneriaki Anda tentang kode yang lambat.
Secara umum, menggunakan peta (tas properti) di tempat objek adalah hal yang lumrah dalam pengembangan perangkat lunak. Ini tidak unik untuk pemrograman fungsional atau jenis bahasa tertentu. Ini mungkin bukan pendekatan idiomatis untuk bahasa tertentu, tetapi ada situasi yang mengharuskannya.
Secara khusus, serialisasi / deserialisasi sering membutuhkan teknik yang serupa.
Hanya beberapa pemikiran umum tentang "peta sebagai objek".
sumber
commonplace
tampaknya sedikit kuat bagiku. Maksud saya ini digunakan seperti yang Anda gambarkan, tetapi juga salah satu dari hal-hal yang terkenal tidak rapuh / rapuh (seperti byte array atau bare pointer) yang dicoba oleh perpustakaan untuk disembunyikan.Itu pembicaraan yang sangat baik oleh seseorang yang benar-benar tahu apa yang dia bicarakan. Saya sarankan pembaca memperhatikan semuanya. Hanya 36 menit lamanya.
Salah satu poin utamanya adalah kesederhanaan membuka peluang untuk perubahan di kemudian hari. Memilih kelas untuk mewakili a
Person
memberikan manfaat langsung dengan membuat API yang dapat diverifikasi secara statis, seperti yang Anda tunjukkan, tetapi itu datang dengan biaya membatasi peluang atau meningkatkan biaya untuk perubahan dan digunakan kembali nanti.Maksudnya adalah bahwa menggunakan kelas mungkin merupakan pilihan yang masuk akal, tetapi harus menjadi pilihan sadar yang datang dengan kesadaran penuh terhadap biayanya, dan programmer secara tradisional melakukan pekerjaan yang sangat buruk memperhatikan biaya-biaya itu, apalagi mempertimbangkannya. Pilihan itu harus dievaluasi kembali ketika kebutuhan Anda tumbuh.
Berikut ini adalah beberapa perubahan kode (satu atau dua di antaranya disebutkan dalam pembicaraan) yang berpotensi lebih mudah menggunakan daftar peta dibandingkan dengan menggunakan daftar
Person
objek:Map
primitif ke dalam format yang dapat ditransmisikan sangat dapat digunakan kembali dan bahkan mungkin disediakan di perpustakaan.Person
Objek mungkin membutuhkan kode khusus untuk menyelesaikan pekerjaan yang sama).Kami memecahkan masalah semacam ini sepanjang waktu, dan memiliki pola dan alat untuk itu, tetapi jarang berhenti untuk memikirkan jika memilih representasi data yang lebih sederhana dan lebih fleksibel pada awalnya akan membuat pekerjaan kami lebih mudah.
sumber
Choosing a class to represent a Person provides the immediate benefit of creating a statically-verifiable API... but that comes with the cost of limiting opportunities or increasing costs for change and reuse later on.
Salah, dan sangat tidak jujur. Ini meningkatkan peluang Anda untuk berubah di kemudian hari, karena ketika Anda melakukan perubahan, kompiler akan secara otomatis menemukan dan menunjukkan kepada Anda setiap tempat yang perlu diperbarui untuk mempercepat seluruh basis kode Anda. Ada dalam kode dinamis, di mana Anda tidak bisa melakukan itu, bahwa Anda benar-benar digabungkan ke pilihan sebelumnya!Jika data memiliki sedikit atau tidak ada perilaku, dengan konten fleksibel yang cenderung berubah, gunakan Peta. IMO, tipikal "javabean" atau "Data Object" yang terdiri dari Model Domain Anemik dengan bidang N, N setter dan N getter, adalah buang-buang waktu. Jangan mencoba untuk mengesankan orang lain dengan struct Anda yang dimuliakan dengan membungkusnya dalam kelas smancy mewah. Jujurlah, jelaskan niat Anda , dan gunakan Peta. (Atau, jika masuk akal untuk domain Anda, JSON atau objek XML)
Jika data memiliki perilaku aktual yang signifikan, alias metode ( Katakan, Jangan Tanyakan ), maka gunakan kelas. Dan tepuk-tepuk diri Anda di belakang untuk menggunakan pemrograman Berorientasi Objek nyata :-).
Jika data memiliki banyak perilaku validasi esensial dan bidang yang diperlukan, gunakan kelas.
Jika data memiliki perilaku validasi dalam jumlah sedang, itu adalah garis batas.
Jika data memunculkan peristiwa perubahan properti, itu sebenarnya lebih mudah dan tidak terlalu membosankan dengan Peta. Cukup tulis subkelas kecil.
Salah satu kelemahan utama menggunakan Peta adalah bahwa pengguna harus memberikan nilai ke Strings, ints, Foos, dll. Jika ini sangat menjengkelkan dan rentan kesalahan, pertimbangkan kelas. Atau pertimbangkan kelas pembantu yang membungkus Peta dengan getter yang relevan.
sumber
API untuk a
map
memiliki dua level.API dapat dijelaskan di peta dengan konvensi. Misalnya pasangan
:api api-validate
bisa ditempatkan di peta atau:api-foo validate-foo
bisa juga konvensi. Peta bahkan dapat menyimpanapi api-documentation-link
.Menggunakan konvensi memungkinkan programmer membuat bahasa khusus domain yang menstandarkan akses lintas "tipe" yang diimplementasikan sebagai peta. Menggunakan
(keys map)
memungkinkan untuk menentukan properti saat runtime.Tidak ada yang ajaib pada peta dan tidak ada yang magis tentang objek. Ini semua pengiriman.
sumber