Bildiğim kadarıyla yıkıcı ve yapıcı olmak üzere sadece iki tür işlev vardır.
Yapıcı işlev, adından da anlaşılacağı gibi, bir şeyi inşa ederken, yıkıcı bir şey bir şeyi yok eder, ama şu anda düşündüğünüz şekilde değil.
Örneğin, işlev
Function<Integer,Integer> f = (x,y) -> x + y
Bir olan yapıcı bir. Bir şey inşa etmeniz gerektiği gibi. Örnekte demeti oluşturdunuz (x, y) . Yapıcı işlevler, sonsuz argümanları işleyememe sorununa sahiptir. Ama en kötüsü, bir tartışmayı öylece açık bırakamazsın. "Peki, x: = 1" diyemezsiniz ve denemek isteyebileceğiniz her y'yi deneyemezsiniz. Tüm demeti her seferinde inşa etmelisiniz
x := 1
. Yani fonksiyonların ne getireceğini görmek y := 1, y := 2, y := 3
istiyorsanız yazmanız gerekir f(1,1) , f(1,2) , f(1,3)
.
Java 8'de, yapıcı bir lambda işlevi kullanmanın pek bir avantajı olmadığından, yapıcı işlevler (çoğu zaman) yöntem referansları kullanılarak ele alınmalıdır. Biraz statik yöntemler gibidirler. Onları kullanabilirsiniz, ancak gerçek bir durumları yoktur.
Diğeri ise yıkıcı olanıdır, bir şeyi alır ve gerektiği kadar parçalara ayırır. Örneğin, yıkıcı işlev
Function<Integer, Function<Integer, Integer>> g = x -> (y -> x + y)
f
yapıcı olan işlevle aynı şeyi yapar . Yıkıcı bir işlevin faydaları, artık sonsuz sayıda argümanın üstesinden gelebilmenizdir, bu özellikle akışlar için uygundur ve argümanları açık bırakabilirsiniz. Tekrar sonuç eğer nasıl olacağını görmek istiyorsanız Yani x := 1
ve y := 1 , y := 2 , y := 3
şunları söyleyebilirsiniz h = g(1)
ve
h(1)
sonucu şudur y := 1
, h(2)
için y := 2
ve h(3)
için y := 3
.
Yani burada sabit bir durumunuz var! Bu oldukça dinamik ve çoğu zaman bir lambdadan istediğimiz şey bu.
Factory gibi modeller, işi sizin için yapan bir işlev koyabilirseniz çok daha kolaydır.
Yıkıcı olanlar birbirleriyle kolayca birleştirilir. Yazı doğruysa, onları istediğiniz gibi oluşturabilirsiniz. Bunu kullanarak (değişmez değerlerle) testi çok daha kolay hale getiren morfizmaları kolayca tanımlayabilirsiniz!
Bunu yapıcı biriyle de yapabilirsiniz, ancak yıkıcı kompozisyon daha güzel ve daha çok bir liste veya bir dekoratör gibi görünür ve yapıcı olan bir ağaca çok benzer. Yapıcı işlevlerle geriye dönük izleme gibi şeyler hiç hoş değil. Yıkıcı bir işlevin (dinamik programlama) kısmi işlevlerini kaydedebilir ve "geriye doğru" yalnızca eski yıkıcı işlevi kullanabilirsiniz. Bu, kodu çok daha küçük ve daha okunaklı hale getirir. Yapıcı işlevlerle, tüm argümanları hatırlamak için az ya da çok sahip olursunuz, bu çok fazla olabilir.
Öyleyse neden yoktan çok BiFunction
soru sorulmasına ihtiyaç var TriFunction
?
Her şeyden önce, çoğu zaman sadece birkaç değere sahip olursunuz (3'ten az) ve sadece bir sonuca ihtiyacınız vardır, bu nedenle normal bir yıkıcı işleve hiç gerek kalmaz, yapıcı bir işlev görür. Ve gerçekten yapıcı bir işleve ihtiyaç duyan monadlar gibi şeyler var. Ancak bunun dışında, neden bir tane olduğu konusunda pek çok iyi neden yok BiFunction
. Bu, kaldırılması gerektiği anlamına gelmez! Monad'larım için ölene kadar savaşırım!
Dolayısıyla, mantıksal bir konteyner sınıfında birleştiremeyeceğiniz çok sayıda argümanınız varsa ve işlevin yapıcı olması gerekiyorsa, bir yöntem referansı kullanın. Aksi takdirde, yeni kazanılan yıkıcı işlev becerisini kullanmaya çalışın, kendinizi çok daha az kod satırı ile çok şey yaparken bulabilirsiniz.