views:

166

answers:

5

I'm writing demo code for an API we've created and I keep running into the same problem where I'm repeating myself, over and over ad nauseum. I am painfully aware that Java is scheduled to have closures added but I don't have access to them now. Here is what is repeated all over the place that I'd like to just box into it's own little corner:

public BarObj Foo(Double..._input){
    try{
        //things that vary per function
        //but everything else...
    } catch(NullException _null){
        m_Logger.error("Null error exception caught in Blah::Foo");

        return null;
    } catch(Exception ex){
        m_Logger.error( ex.getMessage() );

        return null;
    }
}

About the only way I've thought to go around this is by passing a Method into a function which carries with it the try-catch logic and wrapping it all up in another function like so:

public BarObj MyFunc(Double..._input){
    return compose("MyLogic",_input);
}

private BarObj MyLogic(Double..._input) 
    throws Exception{
    //stuff
}

but it looks ugly and carries with it a lot of boilerplate. Is there an easier way to compose functions in Java?

+2  A: 

Try lambdaj. It allows to add a bit of FP to java in a quite light and readable way. In particular in this closure wiki page you can find an example very similar to what you are trying to achieve,

Mario Fusco
A: 

This is obviously your call, but with most API demos I've used I prefer the longer format that you have at the top. After I look over the code I typically do copy-and-paste to verify the API works like I think it does then modify it from there. Changing the format to hide some of the repetative pieces is definately what you want to do for OO development but I think that this kinda demo code is something that the 'clean code gods' would understand :-) .

SOA Nerd
A: 

There is no way of doing this in java, but try using groovy if it is possible for you. The other option you can have similar wrapping is using aspect. see aspectj.

Teja Kantamneni
A: 

I learned the way this is done in Java is to create an interface that has one method. In your code you use classes implementing that interface.

DerMike
+8  A: 

in Java this is very difficult since there is no first class support for functions (unlike clojure or scala and probably other).

However, you can encapsulate the operation in an object:

interface Function<R, T> {

     R call(T... input);
}

then refactor Foo as:

static <R, T> R runFunction(Function<R, T> function, T ... input){
    try{
       return function.call(input);
    } catch(NullPointerException _null){
       m_Logger.error("Null error exception caught in Blah::Foo");
       return null;
    } catch(Exception ex){
       m_Logger.error( ex.getMessage() );
       return null;
    }
}

testcase:

class SumDoubles implements Function<Double, Double> {

    @Override
    public Double call(Double... input) {
        Double sum = 0.0;

        for (Double d : input) {
            sum += d;
        }

        return sum;
    }
}

@Test
public void sum() {
    Double sum = runFunction(new SumDoubles(), 1.0, 2.0, 3.0);
    assertThat(sum, is(6.0));
}
dfa
Would you suggest then that these be made as private classes within the larger `Foo` class? I think that's a fairly nice separation of concerns. Btw, I love Scala.
wheaties