Dalam java.util.function
paket Java 8 , kami memiliki:
- Fungsi : Mengambil satu argumen, menghasilkan satu hasil.
- Konsumen : Mengambil satu argumen, tidak menghasilkan apa-apa.
- Pemasok : Tanpa argumen, menghasilkan satu hasil.
- ... : Kasus lain yang menangani primitif, 2 argumen, dll ...
Tetapi saya perlu menangani kasus " tidak perlu argumen, tidak menghasilkan apa-apa ".
Tidak ada dalam ini java.util.functionnal
.
Jadi, pertanyaannya adalah:
Apa nama ' fungsi yang tidak mengambil argumen dan tidak menghasilkan apa - apa '?
Di Java 8, definisinya adalah:
@FunctionalInterface
public interface InsertANameHere {
void execute();
}
Eksekutor sudah ada dan memiliki tujuan lain: " Objek yang mengeksekusi tugas Runnable yang diajukan ". Tanda tangan tidak cocok ( execute(Runnable):void
) dan bahkan bukan antarmuka fungsional .
Runnable ada, tetapi sangat terkait dengan konteks threading:
- Paketnya
java.lang
bukanjava.util.function
. - Javadoc menyatakan: " Antarmuka Runnable harus diimplementasikan oleh kelas mana pun yang instance-nya dimaksudkan untuk dieksekusi oleh utas ".
- Nama "Runnable" menyarankan beberapa kode yang berjalan di dalam utas.
java
functional-programming
java8
superbob
sumber
sumber
Runnable
sudah usang pada saat ini, karena Runnable juga digunakan oleh kelas lain selainThread
(Executor
misalnya).Runnable
s hanya bisa.run()
denganThread
s. Bahkan mereka sangat umum digunakan untuk tujuan yang dijelaskan dalam pertanyaanjava.util.function
paket.Jawaban:
Pilihan Jawa untuk melakukannya dengan nama yang terpisah untuk setiap kegiatan adalah bodoh. Ini tidak layak ditiru. Namun, jika Anda harus demi konsistensi, atau jika Anda sedang menulis kode perpustakaan yang sangat umum, saran Konrad baik. Saya mungkin melempar
Procedure
ke atas ring.Menggunakan paradigma pseudo-fungsional tidak berarti prinsip penamaan yang normal harus keluar jendela. Antarmuka hampir selalu dinamai sesuai dengan apa yang mereka lakukan , bukan setelah beberapa ide sintaksis generik. Jika fungsi ditempatkan ke dalam tumpukan undo, mereka harus dinamai
UndoFunction
. Jika mereka dipanggil dari acara GUI, mereka harus dinamaiGUIEventHandler
. Teman tidak membiarkan teman mengabadikan konvensi penamaan yang buruk.sumber
Procedure
juga baik-baik saja. Untuk konteksnya, saya sedang mengembangkan perpustakaan umum yang perlu menangani "struktur" semacam ini.Procedure
dari hari pascal saya. AProcedure
memiliki efek samping, aFunction
tidak. Karena Anda tidak mengembalikan nilai, satu-satunya hal yang bisa dilakukan adalah memiliki efek samping.ProcedureRIR<T1,T2>
untukvoid proc(T1, int, T2)
, dan juga untuk jenis lain - mungkin membuat sebagian besar sesuai permintaan daripada mencoba menjejalkan dalam setiap kemungkinan kombinasi jenis.If the functions are placed into an undo stack, they should be named UndoFunction.
Ada perbedaan antara penamaan fungsi dan memberikannya tipe yang berbeda. Dalam gaya fungsional Anda tidak akan membuatUndoFuncton
jenis karena sekarang Anda tidak bisa lewat keflip
,curry
,compose
,filter
,map
, dll Menurut pendapat saya bahwa alasan sebenarnya keputusan Java untuk memberikan fungsi dengan arities berbeda nama yang berbeda adalah bodoh. Tentu saja, jika Anda akan menggunakan efek samping, sebut saja apa pun; Anda sudah membuang komposisi ke luar jendela dan Anda mungkin juga tidak menggunakan fungsi.Di dunia java, ini disebut
Runnable
. Di dunia C #, itu disebutAction
.Tapi, ada nama yang lebih baik yang cocok dengan pandangan yang lebih luas.
Pandangan yang lebih besar tentang hal-hal datang kemudian, ketika Anda memutuskan bahwa selain antarmuka fungsional parameterless Anda juga perlu memiliki antarmuka fungsional serupa yang menerima satu, dua, atau lebih argumen, atau yang mengembalikan nilai. Ketika itu terjadi, Anda akan ingin nama-nama semua entitas itu menjadi isomorfik dan korespondensi satu sama lain.
Jadi, di Jawa, saya memiliki set sendiri antarmuka fungsional yang saya sebut
Procedure
s, didefinisikan sebagai berikut:... (Anda mendapatkan fotonya.)
Dan saya juga memiliki seperangkat antarmuka yang sama yang disebut
Function
s, didefinisikan dengan cara yang sama, dengan parameter generik pertama adalah tipe pengembalian:Jadi, maksud saya di sini adalah
Procedure
nama yang sangat bagus karena cocok dengan pandangan yang lebih luas. Jika nanti Anda memutuskan untuk memiliki antarmuka fungsional yang sama dengan metode yang menerima argumen atau mengembalikan nilai, Anda akan mengalami hal ini.CATATAN: Saya pada dasarnya setuju dengan pernyataan Karl Bielefeldt bahwa "prinsip penamaan normal harus [tidak] keluar jendela" dan bahwa "Antarmuka hampir selalu diberi nama sesuai dengan apa yang mereka lakukan, bukan setelah beberapa ide sintaksis generik." Tetapi perhatikan bahwa bahkan ia mengizinkan "hampir selalu". Kadang-kadang ada kebutuhan untuk (dasarnya anonim) prosedur dan fungsi, dan itulah yang diminta OP, dan itulah yang saya jawab.
Amandemen 2017-11-10:
Anda mungkin bertanya, mengapa
Function1<R,T1>
bukanFunction1<T1,R>
? Itu bisa berjalan baik, tetapi saya memiliki preferensi untuk mengembalikan nilai di sebelah kiri karena saya ingin mengikuti konvensi penamaan 'convert-from' (destination-from-source) sebagai lawan dari 'convert-to' (source-to) -destinasi) konvensi. (Yang lebih merupakan kecelakaan daripada sebuah konvensi, sungguh, dalam arti bahwa kemungkinan besar, tidak ada yang pernah memikirkannya, karena jika mereka memikirkannya sama sekali mereka akan tiba di konvensi 'convert-from'. )Saya membaca tentang ini di Joel Spolksy - Membuat Kode yang Salah Terlihat Salah , ini adalah artikel yang sangat panjang, yang saya sarankan untuk membaca secara keseluruhan, tetapi jika Anda ingin melompat langsung ke kasing yang ada, cari 'TypeFromType', tetapi untuk memberi Anda TL; DR, idenya adalah yang
myint = intFromStr( mystr )
jauh lebih baik daripadamyint = strToInt( mystr )
, karena dalam kasus pertama nama-nama jenisnya dekat dengan nilai yang terkait, sehingga Anda dapat dengan mudah melihat bahwa 'int' cocok dengan 'int' dan 'str' cocok dengan 'str'.Jadi, dengan ekstensi, saya cenderung memesan hal-hal dengan cara mereka akan muncul dalam kode.
sumber
Function1<T1, R>
?Mengapa tidak
Command
? Mengingat bahwa itu tidak memerlukan data dan tidak mengembalikan data, tetapi dengan asumsi bahwa panggilan itu menyebabkan beberapa efek (jika tidak, itu akan benar-benar sia-sia), saya kira itu kira-kira satu-satunya hal yang dapat dilakukannya - memecat suatu tindakan, membuat sesuatu terjadi.Omong-omong, ada juga
Action
delegasi generik di .NET. Tidak seperti Java,Consumer
dapat mengambil dari 0 hingga 16 argumen; dengan kata lain, versi paling sederhana tidak diperlukan - lihat MSDN .Dan karena namanya tidak menyiratkan ada sesuatu untuk "dikonsumsi", itu juga sepertinya pilihan nama yang bagus.
sumber
Command
itu bagus. Ini dapat dikacaukan dengan pola Command tetapi mungkin itu solusinya.Action
lebih dariCommand
. Perintah terdengar lebih seperti sesuatu yang diterima dan dievaluasi, sementara suatu tindakan dieksekusi untuk efek sampingnya.execute()
metode yang dinamai secara tradisional . 0_o '