Uvod u Atlassian Fugue

1. Uvod

Fugue je Java-ova biblioteka tvrtke Atlassian; to je kolekcija komunalnih usluga koje podržavaju Funkcionalno programiranje.

U ovom tekstu usredotočit ćemo se na najvažnije API-je Fugue.

2. Početak rada s fugom

Da bismo počeli koristiti Fugu u našim projektima, moramo dodati sljedeću ovisnost:

 io.atlassian.fuga fuga 4.5.1 

Najnoviju verziju Fugue možemo pronaći na Maven Central.

3. Opcija

Započnimo svoje putovanje gledajući Opcija klase na koju je odgovor Fugue java.util.Izborno.

Kao što možemo pretpostaviti po imenu, Opcija's spremnik koji predstavlja potencijalno odsutnu vrijednost.

Drugim riječima, an Opcija je bilo Neki vrijednost određene vrste ili Nijedna:

Opcija nema = Option.none (); assertFalse (none.isDefined ()); Opcija some = Option.some ("value"); assertTrue (some.isDefined ()); assertEquals ("vrijednost", some.get ()); Opcija možda = Option.option (someInputValue);

3.1. The karta Operacija

Jedan od standardnih API-ja za funkcionalno programiranje je karta() metoda koja omogućuje primjenu osigurane funkcije na temeljne elemente.

Metoda primjenjuje pruženu funkciju na OpcijaVrijednost ako je prisutna:

Opcija some = Option.some ("value") .map (String :: toUpperCase); assertEquals ("VALUE", some.get ());

3.2. Opcija i a Nula Vrijednost

Osim razlika u imenovanju, Atlassian je donio nekoliko izbora za dizajn Opcija koji se razlikuju od Neobvezno; pogledajmo ih sada.

Ne možemo izravno stvoriti prazno Opcija držeći a null vrijednost:

Option.some (null);

Gore navedeno donosi izuzetak.

Međutim, jedan možemo dobiti kao rezultat korištenja karta() operacija:

Opcija some = Option.some ("value") .map (x -> null); assertNull (some.get ());

To nije moguće jednostavno koristiti java.util.Izborno.

3.3. Opcija Is Iterativ

Opcija može se tretirati kao zbirka koja sadrži najviše jedan element, pa ima smisla za nju implementirati Iterativ sučelje.

To uvelike povećava interoperabilnost pri radu s zbirkama / streamovima.

A sada se, na primjer, može povezati s drugom kolekcijom:

Opcija some = Option.some ("value"); Iterable nizovi = Iterables .concat (neki, Arrays.asList ("a", "b", "c"));

3.4. Pretvaranje Opcija do Stream

Budući da je Opcija je Iterable, može se pretvoriti u Stream lako također.

Nakon pretvorbe, Stream instanca će imati točno jedan element ako je opcija prisutna, ili nula u suprotnom:

assertEquals (0, Option.none (). toStream (). count ()); assertEquals (1, Option.some ("value"). toStream (). count ());

3.5. java.util.Izborno Interoperabilnost

Ako nam treba standard Neobvezno implementaciju, možemo je lako dobiti koristeći doObavezno () metoda:

Izborno neobavezno = Option.none () .toO optional (); assertTrue (Option.fromO optional (nije obavezno) .isEmpty ());

3.6. The Opcije Klasa korisnosti

Napokon, Fugue nudi neke korisne metode za rad s njima Opcijas u prikladno imenovanim Opcije razred.

Sadrži metode kao što su filterNije za uklanjanje praznih Opcije iz kolekcije i izravnati za redoming zbirka Opcije u zbirku zatvorenih predmeta, filtrirajući prazne Opcije.

Uz to, sadrži nekoliko varijanti lift metoda koja podiže a Funkcija u a Funkcija>:

Funkcija f = (Integer x) -> x> 0? x + 1: null; Funkcija podignuto = Options.lift (f); assertEquals (2, (long) lifted.apply (Option.some (1)). get ()); assertTrue (lifted.apply (Option.none ()). isEmpty ());

To je korisno kada želimo proslijediti funkciju koje nismo svjesni Opcija na neku metodu koja koristi Opcija.

Imajte na umu da, baš kao i karta metoda, lift ne preslikava nulu na Nijedna:

assertEquals (null, lifted.apply (Option.some (0)). get ());

4. Ili za proračune s dva moguća ishoda

Kao što smo vidjeli, Opcija klasa omogućuje nam da se s nedostatkom vrijednosti nosimo na funkcionalan način.

Međutim, ponekad trebamo vratiti više podataka nego "bez vrijednosti"; na primjer, možda bismo željeli vratiti legitimnu vrijednost ili objekt pogreške.

The Ili klasa pokriva taj slučaj upotrebe.

Primjer Ili može biti a Pravo ili a Lijevo, ali nikad oboje istovremeno.

Prema dogovoru, desno je rezultat uspješnog izračunavanja, dok je lijevo izniman slučaj.

4.1. Konstruiranje an Ili

Možemo dobiti Ili instancu pozivanjem jedne od svoje dvije statičke tvorničke metode.

Mi zovemo pravo ako želimo Ili koji sadrže Pravo vrijednost:

Ili desno = Ili.desno ("vrijednost");

Inače, zovemo lijevo:

Bilo lijevo = Ili.lijevo (-1);

Ovdje naše izračunavanje može vratiti a Niz ili an Cijeli broj.

4.2. Korištenjem Ili

Kad imamo Ili Primjerice, možemo provjeriti je li lijevo ili desno i ponašati se u skladu s tim:

if (ili.isRight ()) {...}

Još zanimljivije je da operacije možemo povezati funkcionalnim stilom:

bilo .map (String :: toUpperCase) .getOrNull ();

4.3. Projekcije

Glavna stvar koja razlikuje bilo koji od ostalih monadičkih alata poput Opcija, probajte, je činjenica da je često nepristran. Jednostavno rečeno, ako pozovemo metodu map (), Ili ne zna treba li surađivati Lijevo ili Pravo strana.

Tu projekcije dobro dođu.

Lijeva i desna projekcija zrcalan su pogled na an Ili koji se fokusiraju na lijevu ili desnu vrijednost, odnosno:

bilo.left () .map (x -> decodeSQLErrorCode (x));

U gornjem isječku koda, ako Ili je Lijevo, decodeSQLErrorCode () primijenit će se na temeljni element. Ako Ili je Pravo, neće. Isto je obrnuto kada koristite pravu projekciju.

4.4. Korisne metode

Kao i sa Opcije, Fugue nudi klasu punu komunalnih usluga za Bilo koji, također, i zove se upravo tako: Bilo koji.

Sadrži metode filtriranja, lijevanja i ponavljanja zbirki Ilis.

5. Rukovanje iznimkama s Probati

Završavamo obilazak tipova podataka „ovaj ili onaj“ u Fugi s drugom varijacijom koja se naziva Probati.

Probati je sličan Ili, ali razlikuje se po tome što je namijenjen radu s iznimkama.

Kao Opcija i za razliku od Ili, Probati je parametriziran za jedan tip, jer je "drugi" tip fiksiran na Iznimka (dok je za Opcija to je implicitno Poništiti).

Dakle, a Probati može biti ili a Uspjeh ili a Neuspjeh:

assertTrue (Try.failure (nova iznimka ("Fail!")). isFailure ()); assertTrue (Try.successful ("OK"). isSuccess ());

5.1. Instanciranje a Probati

Često nećemo stvarati Probati izričito kao uspjeh ili neuspjeh; radije ćemo ga stvoriti iz poziva metode.

Provjereno.od poziva zadanu funkciju i vraća a Probati enkapsuliranje njegove povratne vrijednosti ili bilo koje izbačene iznimke:

assertTrue (Checked.of (() -> "ok"). isSuccess ()); assertTrue (Provjereno.of (() -> {baciti novu iznimku ("ko");}). isFailure ());

Druga metoda, Provjereno.lift, uzima potencijalno bacanje i dizala to u funkciju koja vraća a Probati:

Provjereno.Funkcija throwException = (Niz x) -> {baciti novu iznimku (x); }; assertTrue (Provjereno.lift (throwException) .apply ("ko"). isFailure ());

5.2. Raditi sa Probati

Jednom kad imamo Probati, tri najčešće stvari koje bismo na kraju mogli učiniti s tim su:

  1. vađenje njegove vrijednosti
  2. ulančavanje neke operacije u uspješnu vrijednost
  3. rukovanje iznimkom s funkcijom

Osim toga, očito, odbacivanje Probati ili prenošenje na druge metode, gornje tri nisu jedine mogućnosti koje imamo, ali sve ostale ugrađene metode samo su pogodnost nad ove tri.

5.3. Izdvajanje uspješne vrijednosti

Za izdvajanje vrijednosti koristimo getOrElse metoda:

assertEquals (42, failedTry.getOrElse (() -> 42));

Vraća uspješnu vrijednost ako je prisutna ili neku izračunatu vrijednost u suprotnom.

Ne postoji getOrThrow ili slično, ali od getOrElse ne uhvati nikakvu iznimku, možemo to lako napisati:

someTry.getOrElse (() -> {baciti novi NoSuchElementException ("Ništa za dobiti");});

5.4. Lanciranje poziva nakon uspjeha

U funkcionalnom stilu, funkciju možemo primijeniti na vrijednost uspjeha (ako postoji), a da je prethodno izričito ne izdvojimo.

Ovo je tipično karta metoda koju nalazimo u Opcija, Ili i većina drugih spremnika i zbirki:

Pokušajte aTry = Try.successful (42) .map (x -> x + 1);

Vraća a Probati kako bismo mogli povezati daljnje operacije.

Naravno, imamo i flatMap raznolikost:

Try.successful (42) .flatMap (x -> Try.successful (x + 1));

5.5. Oporavak od iznimki

Imamo analogne operacije mapiranja koje rade s izuzetkom a Probati (ako je prisutan), umjesto njegove uspješne vrijednosti.

Međutim, te se metode razlikuju po tome što imaju značenje za oporavak od iznimke, tj. za stvaranje uspješnog Probati u zadanom slučaju.

Dakle, pomoću možemo proizvesti novu vrijednost oporavak:

Pokušajte se oporaviti = Isprobajte .failure (nova iznimka ("boo!")) .Recover ((iznimka e) -> e.getMessage () + "oporavljeno."); assertTrue (recovery.isSuccess ()); assertEquals ("boo! recovery.", recovery.getOrElse (() -> null));

Kao što vidimo, funkcija oporavka uzima iznimku kao jedini argument.

Ako funkcija oporavka sama baci, rezultat je još jedan neuspjeh Probati:

Pokušaj neuspjeha = Try.failure (nova iznimka ("boo!")). Recovery (x -> {baciti novi RuntimeException (x);}); assertTrue (failure.isFailure ());

Analogno flatMap Zove se oporaviti se s:

Pokušajte se oporaviti = Pokušajte .failure (nova iznimka ("boo!")) .RecoverWith ((iznimka e) -> Try.successful ("opet oporavljena!")); assertTrue (recovery.isSuccess ()); assertEquals ("ponovno oporavljeno!", recovery.getOrElse (() -> null));

6. Ostale komunalne usluge

Pogledajmo sada neke druge uslužne programe u Fugueu, prije nego što ih završimo.

6.1. Parovi

A Par je zaista jednostavna i svestrana struktura podataka, sastavljena od dvije jednako važne komponente, koje Fugue naziva lijevo i pravo:

Parni par = Pair.pair (1, "a"); assertEquals (1, (int) pair.left ()); assertEquals ("a", pair.right ());

Fuga ne nudi mnogo ugrađenih metoda Pars, osim mapiranja i aplikativnog uzorka funktora.

Međutim, ParKoriste se u cijeloj knjižnici i lako su dostupni za korisničke programe.

Sljedeća implementacija Lispa za siromašne osobe udaljena je samo nekoliko tipki!

6.2. Jedinica

Jedinica je nabrajanje s jednom vrijednošću koja treba predstavljati "bez vrijednosti".

To je zamjena za tip vraćanja praznine i Poništiti klase, to uklanja null:

Jedinica doSomething () {System.out.println ("Pozdrav! Nuspojava"); povratna jedinica (); }

Sasvim iznenađujuće, međutim, Opcija ne razumije Jedinica, tretirajući ga kao neku vrijednost umjesto kao nikakvu.

6.3. Statički programi

Imamo nekoliko klasa prepunih statičkih korisnih metoda koje nećemo morati pisati i testirati.

The Funkcije klasa nudi metode koje koriste i transformiraju funkcije na razne načine: sastav, primjena, currying, djelomično korištenje funkcija Opcija, slaba memoizacija i tako dalje.

The Dobavljači klasa pruža sličnu, ali ograničeniju kolekciju uslužnih programa za Dobavljačs, odnosno funkcije bez argumenata.

Interables i Iteratorenapokon, sadrže mnoštvo statičkih metoda za manipuliranje ona dva široko korištena standardna Java sučelja.

7. Zaključak

U ovom smo članku dali pregled biblioteke Fugue tvrtke Atlassian.

Nismo dotakli tečajeve algebre poput Monoidni i Polugrupe jer se ne uklapaju u generalistički članak.

Međutim, o njima i više možete pročitati u Fugue javadocs i izvornom kodu.

Također nismo dodirnuli nijedan opcijski modul koji nudi, na primjer, integracije s Guavom i Scalom.

Provedbu svih ovih primjera i isječaka koda možete pronaći u projektu GitHub - ovo je Maven projekt, pa bi ga trebalo lako uvesti i pokrenuti kao što jest.


$config[zx-auto] not found$config[zx-overlay] not found