Penanganan kesalahan gaya fungsional di Jawa

Selain pendekatan klasik untuk menangani kesalahan menggunakan pengecualian, pendekatan fungsional juga dapat dibedakan.

Alih-alih melempar pengecualian segera, Anda dapat melokalkannya dan kemudian melakukan tindakan tertentu di atasnya.

Misalnya, dalam Scala, kelas Try spesifik digunakan untuk ini.

def inputStreamForURL(url: String): Try[Try[Try[InputStream]]] = parseURL(url).map { u => Try(u.openConnection()).map(conn => Try(conn.getInputStream)) } 

Di dunia Java, menggunakan perpustakaan Vavr, Anda juga bisa menangani kesalahan dengan gaya fungsional.

 Try.of(() -> u.openConnection()).getOrElse(other); 

Di Java 8, kelas opsional ditambahkan untuk bekerja lebih benar dengan tipe null. Ini memungkinkan Anda untuk membungkus suatu objek, yang bisa menjadi nol, dan dengan gaya fungsional lebih aman untuk bekerja dengannya lebih jauh.

Untuk bekerja dengan berbagai jenis pengecualian, Anda dapat menerapkan kelas yang mirip dengan Opsional, yang juga aman untuk thread dan tidak dapat diubah.

 public final class Expected<T, E extends Throwable> { private final T value; private final E error; private Expected() { this.value = null; this.error = null; } private Expected(T value) { this.value = Objects.requireNonNull(value); this.error = null; } private Expected(E error) { this.error = Objects.requireNonNull(error); this.value = null; } public static <T, E extends Throwable> Expected<T, E> of(T value) { return new Expected<>(value); } public static <T, E extends Throwable> Expected<T, E> of(E error) { return new Expected<>(error); } public static <T, E extends Throwable> Expected<T, E> of(Supplier<T> supplier) { try { return new Expected<>(supplier.get()); } catch (Throwable e) { return new Expected<>((E) e); } } public boolean isValue() { return value != null; } public boolean isError() { return error != null; } public T value() { return value; } public E error() { return error; } } 

Juga, untuk memeriksa apakah pengecualian dilemparkan atau tidak, Anda dapat menulis pengunjung sederhana.

 Expected<Integer, SQLException> data = Expected.of(new SQLException()); matches(data, Expected::error, e -> out.println("get error: " + e), Expected::value, v -> out.println("get value: " + v) ); Expected<Integer, ArithmeticException> expression = Expected.of(() -> 4 / 0); matches(expression, Expected::error, e -> out.println("get error: " + e), Expected::value, v -> out.println("get value: " + v) ); 

 public static <T, E extends Throwable> void matches(Expected<T, E> value, Function<Expected<T, E>, E> firstFunction, Consumer<E> firstBranch, Function<Expected<T, E>, T> secondFunction, Consumer<T> secondBranch) { if (value.isError()) { E arg = firstFunction.apply(value); firstBranch.accept(arg); } else { T arg = secondFunction.apply(value); secondBranch.accept(arg); } } 

Di C ++ 23, direncanakan untuk menambahkan kelas yang serupa ke pustaka standar.

Kelas semacam itu bisa menjadi perusahaan opsional yang bagus di perpustakaan Java standar. Tetapi sayangnya, pada saat ini, untuk bekerja dengan pengecualian dalam gaya fungsional, Anda dapat menggunakan perpustakaan Vavr atau menulis kelas Anda sendiri dalam rupa yang Diharapkan.

Kode sumber lengkap kelas dapat dilihat di tautan github:.

Source: https://habr.com/ru/post/id469329/


All Articles