Creata astrazione della struttura if...then...else...
This commit is contained in:
committed by
Fabio Scotto di Santolo
parent
39f49cd0d3
commit
46cdb250e3
@@ -1,11 +1,13 @@
|
||||
package org.gym.fp.fpjava;
|
||||
|
||||
import org.gym.fp.fpjava.demo.AbstractControlStructureDemo;
|
||||
import org.gym.fp.fpjava.demo.FunctionDemo;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
FunctionDemo.run();
|
||||
AbstractControlStructureDemo.run();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package org.gym.fp.fpjava.demo;
|
||||
|
||||
import org.gym.fp.fpjava.type.Effect;
|
||||
import org.gym.fp.fpjava.type.Function;
|
||||
import org.gym.fp.fpjava.type.Result;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.gym.fp.fpjava.type.Case.match;
|
||||
import static org.gym.fp.fpjava.type.Case.when;
|
||||
|
||||
public class AbstractControlStructureDemo {
|
||||
|
||||
public static void run() {
|
||||
doEmailValidationDemo();
|
||||
}
|
||||
|
||||
private static void doEmailValidationDemo() {
|
||||
validate("this.is@my.email");
|
||||
validate(null);
|
||||
validate("");
|
||||
validate("john.doe@acme.com");
|
||||
}
|
||||
|
||||
private static void validate(String email) {
|
||||
final EmailValidation validation = new EmailValidation();
|
||||
final Function<String, Result<String>> emailChecker = validation.emailChecker;
|
||||
final Effect<String> success = validation.success;
|
||||
final Effect<String> failure = validation.failure;
|
||||
emailChecker.apply(email).bind(success, failure);
|
||||
}
|
||||
}
|
||||
|
||||
class EmailValidation {
|
||||
public final Pattern emailPattern =
|
||||
Pattern.compile("^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$");
|
||||
|
||||
public final Effect<String> success =
|
||||
email -> System.out.println("Verification mail sent to " + email);
|
||||
|
||||
public final Effect<String> failure =
|
||||
msg -> System.err.println("Error message logged: " + msg);
|
||||
|
||||
public final Function<String, Result<String>> emailChecker = s -> match(
|
||||
when(() -> Result.success(s)),
|
||||
when(() -> s == null, () -> Result.failure("email must not be null")),
|
||||
when(() -> s.length() == 0, () -> Result.failure("email must not be empty")),
|
||||
when(() -> !emailPattern.matcher(s).matches(), () -> Result.failure("email " + s + " is invalid")));
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.gym.fp.fpjava.type;
|
||||
|
||||
public class Case<T> extends Tuple<Supplier<Boolean>, Supplier<Result<T>>> {
|
||||
|
||||
public Case(Supplier<Boolean> booleanSupplier, Supplier<Result<T>> resultSupplier) {
|
||||
super(booleanSupplier, resultSupplier);
|
||||
}
|
||||
|
||||
private static class DefaultCase<T> extends Case<T> {
|
||||
|
||||
public DefaultCase(Supplier<Boolean> booleanSupplier, Supplier<Result<T>> resultSupplier) {
|
||||
super(booleanSupplier, resultSupplier);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> Case<T> when(Supplier<Boolean> condition, Supplier<Result<T>> value) {
|
||||
return new Case<>(condition, value);
|
||||
}
|
||||
|
||||
public static <T> DefaultCase<T> when(Supplier<Result<T>> value) {
|
||||
return new DefaultCase<>(() -> true, value);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> Result<T> match(DefaultCase<T> defaultCase, Case<T>... matchers) {
|
||||
for (Case<T> aCase : matchers) {
|
||||
if (aCase._1.get()) return aCase._2.get();
|
||||
}
|
||||
return defaultCase._2.get();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package org.gym.fp.fpjava.type;
|
||||
|
||||
public interface Effect<T> {
|
||||
void apply(T t);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package org.gym.fp.fpjava.type;
|
||||
|
||||
public interface Executable {
|
||||
void exec();
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package org.gym.fp.fpjava.type;
|
||||
|
||||
public interface Result<T> {
|
||||
void bind(Effect<T> success, Effect<T> failure);
|
||||
|
||||
static <T> Result<T> failure(String message) {
|
||||
return new Failure<>(message);
|
||||
}
|
||||
|
||||
static <T> Result<T> success(T value) {
|
||||
return new Success<>(value);
|
||||
}
|
||||
|
||||
class Success<T> implements Result<T> {
|
||||
private final T value;
|
||||
|
||||
public Success(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(Effect<T> success, Effect<T> failure) {
|
||||
success.apply(value);
|
||||
}
|
||||
}
|
||||
|
||||
class Failure<T> implements Result<T> {
|
||||
private final String errorMessage;
|
||||
|
||||
public Failure(String msg) {
|
||||
this.errorMessage = msg;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return this.errorMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(Effect success, Effect failure) {
|
||||
failure.apply(errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package org.gym.fp.fpjava.type;
|
||||
|
||||
public interface Supplier<T> {
|
||||
T get();
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
package org.gym.fp.fpjava.type;
|
||||
|
||||
public class Tuple<A, B> {
|
||||
private final A _1;
|
||||
private final B _2;
|
||||
public final A _1;
|
||||
public final B _2;
|
||||
|
||||
public Tuple(A first, B second) {
|
||||
this._1 = first;
|
||||
|
||||
Reference in New Issue
Block a user