Skip to content

Go Programming Style interface contracts for Java with Boon

RichardHightower edited this page Feb 26, 2014 · 1 revision

Boon Home | Boon Source | If you are new to boon, you might want to start here. Simple opinionated Java for the novice to expert level Java Programmer. Low Ceremony. High Productivity. A real boon to Java to developers!

Java Boon - Go Programming Style Interface Contracts for Java with Boon

Go programming added the concept of Interface contracts with no compile time dependencies. Boon adds this to Java.####

Just like Boon added respondsTo(...) for Ruby style object contracts, it also add handles(...) for Go Programming style interface contracts. This allows you to see if an object has a compatible interface. My eventual goal is to use invoke dynamic to make the calling of objects this way a no overhead option. The idea behind Go Programming style interface contracts is that you can mix/match libraries without having to carry around a bunch of jar files. A example of the need for this is in Vertx. Look at the ByteBuffer which just wraps the one from Netty. Now imagine that you are using a lib that uses both Vertx and Netty. You would need to write another buffer around each ByteBuffer. Yuck! Now instead imagine that you used this Go Programming style interface and it was fast enough for what you needed then you would not have to have so many wrappers, and you could even use another lib as long as they were compatible with the interface you needed.

Below is an example of using handles with two objects that implement a FileInterface namely FileObject and StringReaderThing.

        FileObject file = new FileObject();
        StringReaderThing reader = new StringReaderThing(lines("Hi mom", "how are you?"));
        List<Object> list = list(file, reader);



        List <?> openList = list("hi");
        List <?> addList = list(1, 2);

        for (Object object : list) {
            if ( handles(object, FileInterface.class) ) invoke(object, "open", openList);

            if ( respondsTo(object, "add", addList) ) puts ("add", invoke(object, "add", addList));


            if ( handles(object, FileInterface.class) ) {
                puts ( invoke(object, "readLine") );
                puts ( invoke(object, "readLine") );
                invoke(object, "close");
            }
        }

Here is the complete code listing for handles and respondsTo:

package org.boon.core.reflection;


import org.junit.Test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.List;

import static org.boon.Boon.puts;
import static org.boon.Exceptions.die;
import static org.boon.Lists.list;
import static org.boon.Str.lines;
import static org.boon.core.reflection.Reflection.handles;
import static org.boon.core.reflection.Reflection.invoke;
import static org.boon.core.reflection.Reflection.respondsTo;

public class RespondsTo {

    public static interface FileInterface {
        void open(String fileName);

        String readLine();

        void close();
    }


    public static class FileObject {

        boolean readLine;
        boolean openCalled;
        boolean closeCalled;

        boolean addCalled;

        public void open(String fileName) {

            openCalled = true;
            puts("Open ", fileName);
        }

        public String readLine() {
            readLine = true;
            return "read line";
        }

        public int add(int i, int f) {
           addCalled = true;
           return i + f;
        }

        public void close() {
            closeCalled = true;
        }


    }

    public static class StringReaderThing {

        BufferedReader reader = null;

        String contents;

        public StringReaderThing(String contents) {
            this.contents = contents;
        }

        public void open(String fileName) {

            reader = new BufferedReader(new StringReader(contents));

        }

        public String readLine() throws IOException {
            return reader.readLine();
        }

        public void close() throws IOException {
            reader.close();
        }

    }



    @Test
    public void test() {
        FileObject file = new FileObject();
        StringReaderThing reader = new StringReaderThing(lines("Hi mom", "how are you?"));
        List<Object> list = list(file, reader);


        for (Object object : list) {
            if ( respondsTo(object, "open", String.class) ) invoke(object, "open", "hi");

            if ( respondsTo(object, "add", int.class, int.class) ) puts ("add", invoke(object, "add", 1, 2));

            if ( respondsTo(object, "readLine") ) puts ( invoke(object, "readLine") );

            if ( respondsTo(object, "readLine") ) puts ( invoke(object, "readLine") );

            if ( respondsTo(object, "close" ) ) invoke(object, "close");
        }

        boolean ok = file.closeCalled && file.readLine && file.openCalled && file.addCalled || die();


    }



    @Test
    public void testInvoke() {
        FileObject file = new FileObject();
        StringReaderThing reader = new StringReaderThing(lines("Hi mom", "how are you?"));
        List<Object> list = list(file, reader);


        for (Object object : list) {
            if (respondsTo(object, "open", "hi") ) invoke(object, "open", "hi");

            if (respondsTo(object, "add", 1, 2) ) puts ("add", invoke(object, "add", 1, 2));


            if (respondsTo(object, "readLine") ) puts ( invoke(object, "readLine") );

            if (respondsTo(object, "readLine") ) puts ( invoke(object, "readLine") );

            if (respondsTo(object, "close" ) ) invoke(object, "close");
        }

        boolean ok = file.closeCalled && file.readLine && file.openCalled && file.addCalled || die();



    }


    @Test
    public void testInvokeByList() {
        FileObject file = new FileObject();
        StringReaderThing reader = new StringReaderThing(lines("Hi mom", "how are you?"));
        List<Object> list = list(file, reader);



        List <?> openList = list("hi");
        List <?> addList = list(1, 2);

        for (Object object : list) {
            if (respondsTo(object, "open", openList) ) invoke(object, "open", openList);

            if (respondsTo(object, "add", addList) ) puts ("add", invoke(object, "add", addList));


            if (respondsTo(object, "readLine") ) puts ( invoke(object, "readLine") );

            if (respondsTo(object, "readLine") ) puts ( invoke(object, "readLine") );

            if (respondsTo(object, "close" ) ) invoke(object, "close");
        }

        boolean ok = file.closeCalled && file.readLine && file.openCalled && file.addCalled || die();



    }



    @Test
    public void testHandles() {
        FileObject file = new FileObject();
        StringReaderThing reader = new StringReaderThing(lines("Hi mom", "how are you?"));
        List<Object> list = list(file, reader);



        List <?> openList = list("hi");
        List <?> addList = list(1, 2);

        for (Object object : list) {
            if ( handles(object, FileInterface.class) ) invoke(object, "open", openList);

            if ( respondsTo(object, "add", addList) ) puts ("add", invoke(object, "add", addList));


            if ( handles(object, FileInterface.class) ) {
                puts ( invoke(object, "readLine") );
                puts ( invoke(object, "readLine") );
                invoke(object, "close");
            }
        }

        boolean ok = file.closeCalled && file.readLine && file.openCalled && file.addCalled || die();



    }
}

Thoughts

Thoughts? Write me at richard high tower AT g mail dot c-o-m (Rick Hightower).

Further Reading:

If you are new to boon start here:

Why Boon?

Easily read in files into lines or a giant string with one method call. Works with files, URLs, class-path, etc. Boon IO support will surprise you how easy it is. Boon has Slice notation for dealing with Strings, Lists, primitive arrays, Tree Maps, etc. If you are from Groovy land, Ruby land, Python land, or whatever land, and you have to use Java then Boon might give you some relief from API bloat. If you are like me, and you like to use Java, then Boon is for you too. Boon lets Java be Java, but adds the missing productive APIs from Python, Ruby, and Groovy. Boon may not be Ruby or Groovy, but its a real Boon to Java development.

Core Boon Philosophy

Core Boon will never have any dependencies. It will always be able to run as a single jar. This is not just NIH, but it is partly. My view of what Java needs is more inline with what Python, Ruby and Groovy provide. Boon is an addition on top of the JVM to make up the difference between the harder to use APIs that come with Java and the types of utilities that are built into Ruby, Python, PHP, Groovy etc. Boon is a Java centric view of those libs. The vision of Boon and the current implementation is really far apart.

===

Contact Info

blog|[twitter](https://twitter.com/RickHigh|[infoq]http://www.infoq.com/author/Rick-Hightower|[stackoverflow](http://stackoverflow.com/users/2876739/rickhigh)|[java lobby](http://java.dzone.com/users/rhightower)|Other | richard high tower AT g mail dot c-o-m (Rick Hightower)|work|cloud|nosql I also added the ability to invoke by interface. This is a loosely typed interface concept like the Go Programming language in that the class does not have to implement the interface. It only has to implement the methods in the interface. This allows loosely coupled (no jar dependencies) contracts like Go, or so I hope.

Clone this wiki locally