Skip to content

Reader : functional dependency injection

johnmcclean-aol edited this page Nov 22, 2016 · 3 revisions

Reader monad

The Reader class allows us to transform functions, by composing them.

E.g given two functions, one that maps from T to R and another from R to R1..

Function<T, R> fn;
Function<? super R, ? extends R1> fn2;

We can combine them to create a single function that maps from T to R1

Function<T,R1> composed = fn.andThen(fn2)

Reader allows us to map and flatMap functions in the manner of elements within a Stream, composing them together into a single function as we do so.

Functional Dependency Injection

Normally in Java we will inject our dependencies into a class, perhaps using a framework or by a chain of factory methods, so that they are there when we execute a method that needs them. An alternative approach is, rather than execute the code that needs the dependency immediately, rather return a Function that accepts the dependency needed and have that Function execute the code.

e.g. a traditional Java service

class Service{
     DAO userDao;
   
     public User loadUser(long id){
       return dao.loadUser(id);
     }
}

could become

class Service{
     
     public Function<Dao,User> loadUser(long id){
       return dao->dao.loadUser(id);
     }
}

Further more if we refactor this to use [Reader] instead of Function (Reader extends Function and is also a FunctionalInterface) we can manipulate the returned Function and build a chain of method calls, that for example, work with the returned User - even though we won't have the User until we supply the DAO and execute the function at the very top level.

class Service{
     
     public Reader<Dao,User> loadUser(long id){
       return dao->dao.loadUser(id);
     }
}
Clone this wiki locally