Sejauh yang saya tahu, hanya ada dua macam fungsi, destruktif dan konstruktif.
Sementara fungsi konstruktif, seperti namanya, mengkonstruksi sesuatu, fungsi destruktif menghancurkan sesuatu, tetapi tidak dengan cara yang mungkin Anda pikirkan sekarang.
Misalnya fungsinya
Function<Integer,Integer> f = (x,y) -> x + y
adalah salah satu yang konstruktif . Seperti yang Anda butuhkan untuk membangun sesuatu. Dalam contoh Anda membuat tupel (x, y) . Fungsi konstruktif memiliki masalah, karena tidak mampu menangani argumen yang tak terbatas. Tetapi yang terburuk adalah, Anda tidak bisa membiarkan argumen tetap terbuka. Anda tidak bisa hanya mengatakan "baiklah, biarkan x: = 1" dan coba setiap y yang mungkin ingin Anda coba. Anda harus membangun setiap kali seluruh tupel dengan
x := 1
. Jadi jika Anda ingin melihat apa fungsi kembali untuk y := 1, y := 2, y := 3
Anda harus menulis f(1,1) , f(1,2) , f(1,3)
.
Di Java 8, fungsi konstruktif harus ditangani (sebagian besar waktu) dengan menggunakan referensi metode karena tidak banyak keuntungan menggunakan fungsi lambda konstruktif. Mereka agak seperti metode statis. Anda dapat menggunakannya, tetapi tidak memiliki status nyata.
Jenis lainnya adalah yang merusak, ia mengambil sesuatu dan membongkar sejauh yang dibutuhkan. Misalnya fungsi destruktif
Function<Integer, Function<Integer, Integer>> g = x -> (y -> x + y)
melakukan hal yang sama dengan fungsi f
yang konstruktif. Manfaat dari fungsi destruktif adalah, Anda sekarang dapat menangani argumen tak terbatas, yang sangat nyaman untuk aliran, dan Anda dapat membiarkan argumen tetap terbuka. Jadi jika Anda ingin melihat lagi seperti apa hasilnya jika x := 1
dan y := 1 , y := 2 , y := 3
, Anda dapat mengatakan h = g(1)
dan
h(1)
merupakan hasil untuk y := 1
, h(2)
untuk y := 2
dan h(3)
untuk y := 3
.
Jadi di sini Anda memiliki keadaan tetap! Itu cukup dinamis dan seringkali itulah yang kami inginkan dari lambda.
Pola seperti Pabrik jauh lebih mudah jika Anda bisa menggunakan fungsi yang bekerja untuk Anda.
Yang merusak mudah digabungkan satu sama lain. Jika jenisnya benar, Anda dapat membuatnya sesuka Anda. Dengan menggunakan itu, Anda dapat dengan mudah menentukan morfisme yang membuat pengujian (dengan nilai yang tidak dapat diubah) jauh lebih mudah!
Anda juga dapat melakukannya dengan yang konstruktif, tetapi komposisi yang merusak terlihat lebih bagus dan lebih seperti daftar atau dekorator, dan yang konstruktif terlihat sangat mirip dengan pohon. Dan hal-hal seperti mundur dengan fungsi konstruktif tidak baik. Anda dapat menyimpan sebagian fungsi dari fungsi destruktif (pemrograman dinamis), dan pada "backtrack" gunakan saja fungsi destruktif lama. Itu membuat kode jauh lebih kecil dan lebih mudah dibaca. Dengan fungsi konstruktif Anda memiliki lebih banyak atau lebih sedikit untuk mengingat semua argumen, yang bisa jadi banyak.
Jadi mengapa ada kebutuhan BiFunction
harus lebih banyak pertanyaan daripada mengapa tidak ada TriFunction
?
Pertama-tama, sering kali Anda hanya memiliki sedikit nilai (kurang dari 3) dan hanya memerlukan hasil, jadi fungsi destruktif yang normal tidak akan diperlukan sama sekali, fungsi konstruktif sudah cukup. Dan ada hal-hal seperti monad yang sangat membutuhkan fungsi konstruktif. Tapi selain itu, sebenarnya tidak ada banyak alasan bagus mengapa ada BiFunction
. Yang tidak berarti itu harus dihapus! Saya berjuang untuk Monads saya sampai saya mati!
Jadi, jika Anda memiliki banyak argumen, yang tidak dapat Anda gabungkan ke dalam kelas container yang logis, dan jika Anda membutuhkan fungsi yang konstruktif, gunakan referensi metode. Jika tidak, cobalah menggunakan kemampuan baru yang diperoleh dari fungsi destruktif, Anda mungkin menemukan diri Anda melakukan banyak hal dengan baris kode yang jauh lebih sedikit.