Bevezetés az Atlassian Fugue-ba

1. Bemutatkozás

A Fugue egy Java könyvtár az Atlassian által; ez a segédprogramok gyűjteménye Funkcionális programozás.

Ebben az írásban a legfontosabb Fugue API-kra összpontosítunk és felfedezzük őket.

2. A Fugue használatának megkezdése

A Fugue használatának megkezdéséhez a következő függőséget kell hozzáadnunk:

 io.atlassian.fugue fúga 4.5.1 

A Fugue legújabb verzióját megtalálhatjuk a Maven Central-on.

3. választási lehetőség

Kezdjük az utunkat azzal, hogy megnézzük a választási lehetőség osztály, amire Fugue válasza java.util.Opcionális.

Ahogy a név alapján kitalálhatjuk, Választási lehetőség's egy potenciálisan hiányzó értéket képviselő tároló.

Más szavakkal, egy választási lehetőség az egyik Néhány egy bizonyos típusú vagy ill Egyik sem:

Option none = Option.none (); assertFalse (none.isDefined ()); Néhány opció = Option.some ("érték"); assertTrue (néhány.isDefined ()); assertEquals ("érték", néhány.get ()); Lehetséges opció = Option.option (someInputValue);

3.1. A térkép Művelet

Az egyik szabványos funkcionális programozási API az térkép() módszer, amely lehetővé teszi egy adott függvény alkalmazását az alapul szolgáló elemekre.

A módszer a megadott függvényt alkalmazza a választási lehetőségÉrtéke, ha van:

Néhány opció = Option.some ("érték") .map (String :: toUpperCase); assertEquals ("VALUE", néhány.get ());

3.2. választási lehetőség és a Nulla Érték

A különbségek megnevezése mellett az Atlassian néhány tervezési döntést is hozott választási lehetőség amelyek különböznek a Választható; nézzük most meg őket.

Nem hozhatunk létre közvetlenül nem üreset választási lehetőség tartja a nulla érték:

Option.some (null);

A fentiek kivételt vetnek ki.

A. Használatával azonban kaphatunk egyet térkép() művelet:

Néhány opció = Option.some ("érték") .map (x -> null); assertNull (néhány.get ());

Ez nem lehetséges, ha egyszerűen használja java.util.Opcionális.

3.3. I. lehetőségs Iterálható

választási lehetőség lehet kezelni, mint olyan gyűjtemény, amely maximum egy elemet tartalmaz, ezért van értelme a Iterálható felület.

Ez nagymértékben növeli az interoperabilitást a gyűjteményekkel / folyamokkal való munka során.

És most például összefűzhető egy másik kollekcióval:

Néhány opció = Option.some ("érték"); Iterálható karakterláncok = Iterables .concat (some, Arrays.asList ("a", "b", "c"));

3.4. Konvertálás választási lehetőség nak nek Folyam

Mivel egy választási lehetőség egy Iterable, átalakítható a-vá Folyam könnyen is.

Konvertálás után a Folyam a példánynak pontosan egy eleme lesz, ha az opció jelen van, vagy nulla esetben:

assertEquals (0, Option.none (). toStream (). count ()); assertEquals (1, Option.some ("érték"). toStream (). count ());

3.5. java.util.Opcionális Átjárhatóság

Ha szükségünk van egy szabványra Választható megvalósítását, könnyen megszerezhetjük a opcionális () módszer:

Opcionális választható = Option.none () .toOptional (); assertTrue (Option.fromOptional (opcionális) .isEmpty ());

3.6. A Opciók Segédosztály

Végül a Fugue néhány hasznos módszert kínál a munkához választási lehetőségs a találóan megnevezett Opciók osztály.

Olyan módszereket tartalmaz, mint a filterNone az üres eltávolításához Opciók gyűjteményből, és lelapul fordulásraing gyűjteménye Opciók zárt objektumok gyűjteményébe, üresen kiszűrve Opciók.

Ezenkívül a emel módszer, amely felemeli a Funkció ba be Funkció>:

F = (x egész szám) -> x> 0? x + 1: null; Funkció felemelt = Opciók.lift (f); assertEquals (2, (hosszú) feloldva.alkalmazzon (Option.some (1)). get ()); assertTrue (lifted.apply (Option.none ()). isEmpty ());

Ez akkor hasznos, ha olyan funkciót akarunk átadni, amely nincs tisztában vele választási lehetőség valamilyen módszerhez választási lehetőség.

Vegye figyelembe, hogy ugyanúgy, mint a térkép módszer, emel nem leképezi a nullát Egyik sem:

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

4. Bármelyik két lehetséges kimenetelű számításokhoz

Mint láttuk, a választási lehetőség osztály lehetővé teszi számunkra, hogy funkcionálisan kezeljük az érték hiányát.

Néha azonban több információt kell visszaadnunk, mint az „nincs érték”; például visszaadhatunk egy jogos értéket vagy egy hibaobjektumot.

A Bármelyik osztály lefedi azt a használati esetet.

Példája Bármelyik lehet a Jobb vagy a Balra, de soha nem mindkettőt egyszerre.

Megállapodás szerint a jobb a sikeres számítás eredménye, míg a bal a kivételes eset.

4.1. Egy Bármelyik

Megszerezhetünk egy Bármelyik például a két statikus gyári módszer egyikének meghívásával.

Hívjuk jobb ha szeretnénk egy Bármelyik tartalmazó Jobb érték:

Bármelyik helyes = Vagy vagy jobb ("érték");

Ellenkező esetben hívunk bal:

Vagy balra, vagy balra (-1);

Itt a számításunk akár a Húr vagy egy Egész szám.

4.2. Egy Bármelyik

Amikor van egy Bármelyik Például ellenőrizhetjük, hogy bal vagy jobb, és ennek megfelelően járunk el:

if (vagy.isRight ()) {...}

Érdekesebb, hogy működéseket láncolhatunk funkcionális stílus segítségével:

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

4.3. Vetítések

A legfontosabb dolog, amely megkülönbözteti bármely más monád eszközt, mint például Opció, próbáld, az a tény, hogy gyakran elfogulatlan. Egyszerűen fogalmazva, ha a map () metódust hívjuk, Bármelyik nem tudja, hogy működjön együtt Bal vagy Jobb oldal.

Itt jönnek jól az előrejelzések.

A bal és a jobb előrejelzés az an tükrös nézete Bármelyik amelyek a bal vagy a jobb értékre összpontosítanak, illetve:

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

A fenti kódrészletben, ha Bármelyik van Balra, dekódoljaSQLErrorCode () az alapul szolgáló elemre kerül alkalmazásra. Ha Bármelyik van Jobb, nem fog. Ugyanez fordítva, ha a megfelelő vetítést használja.

4.4. Segédprogram módszerek

Mint Opciók, A Fugue egy osztályt tartalmaz, amely tele van a Eithers, és csak így hívják: Eithers.

Módszereket tartalmaz a. Gyűjteményeinek szűrésére, átküldésére és iterálására Bármelyiks.

5. Kivételek kezelése Próbáld ki

Vagy a, vagy az ilyen adattípusok bemutatását a Fugue-ban egy másik variációval zárjuk Próbáld ki.

Próbáld ki hasonló Bármelyik, de abban különbözik, hogy kivételekkel való munkára szánja.

Mint választási lehetőség és ellentétben Bármelyik, Próbáld ki paraméterezve van egyetlen típuson keresztül, mert a „másik” típus rögzítve van Kivétel (míg a választási lehetőség hallgatólagosan Üres).

Szóval, a Próbáld ki lehet akár a Siker vagy a Kudarc:

assertTrue (Try.failure (új kivétel ("Fail!")). isFailure ()); assertTrue (Try.successful ("OK"). isSuccess ());

5.1. Instantálás a Próbáld ki

Gyakran nem fogunk létrehozni egy Próbáld ki kifejezetten sikerként vagy kudarcként; inkább létrehozunk egyet egy metódushívásból.

Ellenőrizték meghív egy adott függvényt és visszaadja a Próbáld ki a visszatérési értéket vagy bármilyen kivételt összefoglalva:

assertTrue (Ellenőrizve. (() -> "ok"). isSuccess ()); assertTrue (Ellenőrizve. (() -> {új kivétel kivetése ("ko");}). isFailure ());

Egy másik módszer, Ellenőrzött.lift, potenciálisan dobó funkciót tölt be és felvonók a függvényt adja vissza Próbáld ki:

Ellenőrizve. Függvény dobásaException = (String x) -> {dobja az új Exceptiont (x); }; assertTrue (Ellenőrzött.lift (dobásException) .apply ("ko"). isFailure ());

5.2. Dolgozni vele Próbáld ki

Miután megvan a Próbáld ki, a három leggyakoribb dolog, amit végső soron el akarunk kezdeni vele:

  1. értékének kinyerése
  2. bizonyos műveletek láncolása a sikeres értékhez
  3. a kivétel kezelése egy funkcióval

Emellett nyilvánvalóan a Próbáld ki vagy átadva más módszereknek, a fenti három nem az egyetlen lehetőségünk, de az összes többi beépített módszer csak kényelmet jelent e háromhoz képest.

5.3. A sikeres érték kibontása

Az érték kinyeréséhez a getOrElse módszer:

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

Visszaadja a sikeres értéket, ha van, vagy más módon kiszámított értéket.

Nincs getOrThrow vagy hasonló, de azóta getOrElse nem fog kivételt tenni, könnyen megírhatjuk:

someTry.getOrElse (() -> {dobj új NoSuchElementException-t ("Nincs mit beszerezni";});

5.4. Hívások láncolása a siker után

Funkcionális stílusban alkalmazhatunk egy függvényt a sikerértékre (ha van) anélkül, hogy azt először kifejezetten kibontanánk.

Ez a tipikus térkép módszer, amelyben megtaláljuk választási lehetőség, Bármelyik és a legtöbb egyéb konténer és gyűjtemény:

Próbálja aTry = Próbáld.sikeres (42) .térkép (x -> x + 1);

Visszaadja a Próbáld ki így további műveleteket láncolhatunk.

Természetesen nekünk is van flatMap fajta:

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

5.5. Felépülés a kivételektől

Analóg leképezési műveleteink vannak, amelyek az a kivételével működnek Próbáld ki (ha van), nem pedig a sikeres értéke.

Ezek a módszerek azonban abban különböznek egymástól, hogy jelentésük az a kivétel alól kilábalni, vagyis sikereset produkálni Próbáld ki alapértelmezett esetben.

Így új értéket tudunk előállítani visszaszerez:

Próbáld meg helyreállítani = Próbáld ki .failure (új kivétel ("boo!")) .Recover ((e kivétel) -> e.getMessage () + "helyreállt". assertTrue (helyreállítás.isSuccess ()); assertEquals ("boo! helyreállt.", recovery.getOrElse (() -> null));

Mint láthatjuk, a helyreállítási függvény a kivételt veszi egyetlen argumentumnak.

Ha a helyreállítási funkció maga dob, akkor az eredmény egy másik sikertelen Próbáld ki:

Try fail = Try.failure (new Exception ("boo!")). Recovery (x -> {dobjon új RuntimeException (x);}); assertTrue (hiba.isFailure ());

Az analóg flatMap nak, nek hívják helyreállítani:

Próbáld meg helyreállítani = Próbáld ki .failure (új kivétel ("boo!")) .RecoverWith ((e kivétel) -> Try.successful ("újra helyreállt!")); assertTrue (helyreállítás.isSuccess ()); assertEquals ("újra helyreállt!", helyreállítás.getOrElse (() -> null));

6. Egyéb segédprogramok

Most nézzük meg gyorsan a Fugue néhány egyéb segédprogramját, mielőtt összecsomagolnánk.

6.1. Párok

A Pár egy igazán egyszerű és sokoldalú adatszerkezet, amely két ugyanolyan fontos összetevőből áll, amelyeket a Fugue hív bal és jobb:

Páros pár = Pár.pár (1, "a"); assertEquals (1, (int) pár.balra ()); assertEquals ("a", pair.right ());

A Fugue nem sok beépített módszert kínál a Párs a térképezés és az alkalmazandó functor minta mellett.

Azonban, PárAz egész könyvtárat használják, és könnyen elérhetők a felhasználói programok számára.

A következő szegény ember a Lisp-t csak néhány gombnyomással elérhető!

6.2. Mértékegység

Mértékegység egy olyan értékű enum, amelynek egyetlen értéke van, és azt jelenti, hogy „nincs érték”.

Ez helyettesíti a void return típust és Üres osztály, ez megszűnik nulla:

Unit doSomething () {System.out.println ("Hello! Mellékhatás"); visszatérő egység (); }

Meglepetésre azonban választási lehetőség nem érti Mértékegység, úgy kezelik, mint valami értéket, semmilyen helyett.

6.3. Statikus segédprogramok

Van néhány olyan osztály, amely tele van statikus segédprogramokkal, amelyeket nem kell írnunk és tesztelnünk.

A Funkciók osztály olyan módszereket kínál, amelyek különböző módon használják és átalakítják a függvényeket: összetétel, alkalmazás, curry, részleges függvények használata választási lehetőség, gyenge memoizálás stb.

A Beszállítók osztály a segédprogramok hasonló, de korlátozottabb gyűjteményét biztosítja a Támogatós, vagyis argumentum nélküli funkciók.

Iterable és Iterátorokvégül számos statikus módszert tartalmaz a két széles körben használt standard Java interfész kezelésére.

7. Következtetés

Ebben a cikkben áttekintést adtunk az Atlassian fúga könyvtáráról.

Nem nyúltunk hozzá az algebra-nehéz osztályokhoz Monoid és Félcsoportok mert nem férnek bele egy generalista cikkbe.

Azonban olvashat róluk és még sok másról a Fugue javadocs és a forráskódban.

Nem érintettünk egyetlen olyan opcionális modult sem, amely például a Guava és a Scala integrációját kínálja.

Ezeknek a példáknak és kódrészleteknek a megvalósítása megtalálható a GitHub projektben - ez egy Maven projekt, ezért könnyen importálhatónak és futtathatónak kell lennie.