Showing posts with label Cyclops. Show all posts
Showing posts with label Cyclops. Show all posts

Thursday, 25 June 2015

Strategy Pattern in Java 8

These are two examples on how to implement a Strategy pattern design using Java 8 functional style together with Cyclops pattern matching and Hamcrest libraries.

PrintDependingOnInput method is a strategy that will System.println some message based on the log passed.

AddPrefix is another strategy that will add a prefix to a message based on the message content.

package com.marco.patternmatching; 

 

import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.startsWith;
import static org.hamcrest.core.AllOf.allOf;
import java.util.ArrayList;
import java.util.List;
import com.aol.cyclops.matcher.builders.Matching; 

 

public class FunctionalStrategy {

  public static void main(String[] args) {
     List<String> toTest = new ArrayList<>();
     toTest.add("INFO everything is fine");
     toTest.add("WARN something weird happened");
     toTest.add("ERROR NullPointerException");
     toTest.add("ERROR IOException");
     
     toTest.stream().forEach(FunctionalStrategy::printDependingOnInput);

     System.out.println("--------------------");

     List<String> messages = new ArrayList<>();
     messages.add("everything is fine");
     messages.add("something weird happened");
     messages.add("NullPointerException");
     messages.add("IOException");

     messages.stream().map(FunctionalStrategy::addPrefix).forEach(System.out::println);
  }

        
  public static void printDependingOnInput(String log) {

     Matching
        .when().isMatch(startsWith("INFO"))
                   .thenConsume(System.out::println)
        .when().isMatch(startsWith("WARN"))
                   .thenConsume(message -> System.out.println("Found one warning : " + message))
        .when().isMatch(allOf(startsWith("ERROR"), containsString("NullPointerException")))
                   .thenConsume(message -> System.err.println(message))
        .when().isMatch(allOf(startsWith("ERROR"), containsString("IOException")))
                   .thenConsume(message -> System.err.println(message + " Retrying a couple of times"))
        .match(log);

   }

   public static String addPrefix(String log) {

     return Matching
        .when().isMatch(allOf(not(containsString("Exception")), not(containsString("weird"))))
                    .thenApply(message -> "INFO " + message)
        .when().isMatch(containsString("weird"))
                    .thenApply(message -> "WARN " + message)
        .when().isMatch(containsString("Exception"))
                    .thenApply(message -> "ERROR " + message)
        .match(log).get();

  }
}


Nice and clean ;)

Friday, 12 June 2015

Java 8, easier with Cyclops : Try


Cyclops is another promising open source library from John McClean in AOL, that aims to extends and simplify Java 8 functionality.

One of its feature is Try that offers an alternative way to manage exception handling.

Imagine you have a method that load files from some location :

private List<File> loadFiles() { 
     return Lists.newArrayList(new File("somePath_one"), new File("somePath_two"));
} 

Many things could go wrong there, file does not exist, network is down, etc.
 
Traditionally, we could have manage exceptions surrounding the loadFiles() method with try and catch and handle each exception within a catch statement.

Cyclops Try made things easier and cleaner :

Try.withCatch(this::loadFiles, Exception.class)


    .onFail(FileNotFoundException.class, e -> System.err.println("Something specific to do here if file does not exists" + e))


    .onFail(IOException.class, e -> System.err.println("Maybe retry a couple of times before dropping the operation" + e))


    .forEach(System.out::println);

Based on the exception, different functions can be triggered.

http://media.giphy.com/media/U0uowJVj7ewO4/giphy.gif