Bagaimana cara membuat sistem yang memiliki semua hal berikut :
- Menggunakan fungsi murni dengan objek yang tidak berubah.
- Hanya meneruskan ke data fungsi yang dibutuhkan fungsi, tidak lebih (yaitu tidak ada objek status aplikasi besar)
- Hindari terlalu banyak argumen pada fungsi.
- Hindari harus membuat objek baru hanya untuk tujuan mengemas dan membongkar parameter ke fungsi, hanya untuk menghindari terlalu banyak parameter yang diteruskan ke fungsi. Jika saya akan mengemas beberapa item ke fungsi sebagai objek tunggal, saya ingin objek itu menjadi pemilik data itu, bukan sesuatu yang dibangun sementara
Sepertinya saya bahwa Negara monad melanggar aturan # 2, meskipun itu tidak jelas karena itu dijalin melalui monad.
Saya punya perasaan saya perlu menggunakan Lensa entah bagaimana, tetapi sangat sedikit yang ditulis tentang itu untuk bahasa non-Fungsional.
Latar Belakang
Sebagai latihan, saya mengubah salah satu aplikasi saya yang ada dari gaya berorientasi objek ke gaya fungsional. Hal pertama yang saya coba lakukan adalah membuat sebanyak mungkin inti-dalam dari aplikasi.
Satu hal yang saya dengar adalah bagaimana mengelola "Negara" dalam bahasa yang benar-benar fungsional, dan ini yang saya yakini dilakukan oleh State Monads, adalah bahwa secara logis, Anda menyebut fungsi murni, "melintas di negara bagian dunia apa adanya ", maka ketika fungsi kembali, ia mengembalikan kepada Anda keadaan dunia sebagaimana telah berubah.
Sebagai ilustrasi, cara Anda dapat melakukan "hello world" dengan cara yang benar-benar fungsional agak mirip, Anda meneruskan program Anda yang menyatakan layar, dan menerima kembali keadaan layar dengan "hello world" yang tercetak di atasnya. Jadi secara teknis, Anda melakukan panggilan ke fungsi murni, dan tidak ada efek samping.
Berdasarkan hal itu, saya memeriksa aplikasi saya, dan: 1. Pertama, letakkan semua status aplikasi saya menjadi satu objek global (GameState) 2. Kedua, saya membuat GameState tidak dapat diubah. Anda tidak bisa mengubahnya. Jika Anda butuh perubahan, Anda harus membuat yang baru. Saya melakukan ini dengan menambahkan copy-constructor, yang secara opsional mengambil satu atau lebih bidang yang berubah. 3. Untuk setiap aplikasi, saya mengirimkan GameState sebagai parameter. Dalam fungsi, setelah melakukan apa yang akan dilakukan, itu menciptakan GameState baru dan mengembalikannya.
Bagaimana saya memiliki inti fungsional murni, dan loop di luar yang memberi makan GameState itu ke loop alur kerja utama aplikasi.
Pertanyaan saya:
Sekarang, masalah saya adalah, GameState memiliki sekitar 15 objek abadi yang berbeda. Banyak fungsi di level terendah hanya beroperasi pada beberapa objek tersebut, seperti menjaga skor. Jadi, katakanlah saya memiliki fungsi yang menghitung skor. Hari ini, GameState diteruskan ke fungsi ini, yang mengubah skor dengan membuat GameState baru dengan skor baru.
Sesuatu tentang itu sepertinya salah. Fungsi tidak membutuhkan keseluruhan GameState. Itu hanya membutuhkan objek Skor. Jadi saya memperbaruinya untuk memberikan Skor, dan mengembalikan Skor saja.
Itu sepertinya masuk akal, jadi saya melangkah lebih jauh dengan fungsi-fungsi lain. Beberapa fungsi akan mengharuskan saya untuk lulus dalam 2, 3 atau 4 parameter dari GameState, tetapi ketika saya menggunakan pola tersebut sepanjang inti luar aplikasi, saya memberikan lebih banyak status aplikasi. Seperti, di bagian atas loop alur kerja, saya akan memanggil metode, yang akan memanggil metode yang akan memanggil metode, dll., Semua jalan ke tempat skor dihitung. Itu berarti skor saat ini diteruskan melalui semua lapisan itu hanya karena fungsi di bagian paling bawah akan menghitung skor.
Jadi sekarang saya memiliki fungsi dengan terkadang puluhan parameter. Saya bisa meletakkan parameter-parameter itu ke dalam objek untuk menurunkan jumlah parameter, tapi kemudian saya ingin kelas itu menjadi lokasi utama dari status aplikasi negara, daripada objek yang dibangun pada saat panggilan hanya untuk menghindari lewat dalam beberapa parameter, dan kemudian ekstrak mereka.
Jadi sekarang saya bertanya-tanya apakah masalah yang saya miliki adalah bahwa fungsi saya bersarang terlalu dalam. Ini adalah hasil dari ingin memiliki fungsi kecil, jadi saya refactor ketika suatu fungsi menjadi besar, dan membaginya menjadi beberapa fungsi yang lebih kecil. Tetapi melakukan hal itu menghasilkan hierarki yang lebih dalam, dan apa pun yang dilewatkan ke fungsi dalam perlu dialihkan ke fungsi luar bahkan jika fungsi luar tidak beroperasi pada objek-objek itu secara langsung.
Sepertinya hanya lewat di GameState sepanjang jalan menghindari masalah ini. Tetapi saya kembali ke masalah semula dengan memberikan lebih banyak informasi ke suatu fungsi daripada fungsi yang dibutuhkan.