Wednesday, January 27, 2016

Using Traits in Java 8

In one of my earlier articles I mentioned a programming component called "traits". These constructs have existed for many years in other programming languages like Scala and PHP, but have only recently been available through default methods in Java. I will not go into the possibilities with using traits in this article, but I will show you a neat trick we use a lot at Speedment that you can use if you ever need to stream over a collection of different objects and separate those that fulfill a number of traits.

Say that you have two noun classes Person and Elephant. There is no reason really why persons and elephants should belong to the same super class; elephants are intelligent four-legged creatures and most humans are not. You might still find the two of them in the same computer system and sometimes you even need to store them in the same collection. One way of operating on this collection of various living beings without making them share a common ancestor, (which would totally be just a theory), you can give them similar traits.

Take a look at this interface:


interface HasName extends Document {
    final String NAME = "name";

    default String getName() {
        return get(NAME);
    }
    
    default void setName(String name) {
        put(NAME, name);
    }
}

Using the Abstract Document Pattern presented earlier, the trait can set and get the attribute "name" from a map. If we now want to iterate over our collection of many living things that might or might not implement our specified traits, we can easily do it like this:


final Set<Object> livingBeings = new HashSet<>();

livingBeings.add(new Person(...));
livingBeings.add(new Person(...));
livingBeings.add(new Elephant(...));

livingBeings.stream()
    .filter(HasName.class::isInstance)
    .filter(HasAge.class::isInstance)
    .filter(HasWeight.class::isInstance)
    .map(p -> (HasName & HasAge & HasWeight) p)
    .forEach(p ->
        System.out.println(
            p.getName() + " is " +
            p.getAge() + " years old and weighs " +
            p.getWeight() + " pounds."
        )
    );

Using the and-character (&) we can cast instances that implement all the required traits into a dynamic type, without them sharing an ancestor.

Was this interesting? In the following article I present a more formal definition of the Trait Pattern in java.

Tuesday, January 19, 2016

Building Reactive Systems with JavaFX

JavaFX is the new standard library for building graphical applications in Java, but many programmers out there is still stuck with Swing or even (tremble) AWT. A lot has happened in the 20 years java has been around. When I began looking into the JavaFX libraries two years ago for the Speedment UI I found many things fascinating! Here are a few tips on how you can use many of the new awesome features in the JavaFX toolkit to build reactive and fast applications!

1. Property Values

If you have snooped around in the JavaFX components you must have come across the term Property. Almost every value in the FX library can be observed, the width of a divider, the size of an image, the text in a label, the children of a list as well as the status of a checkbox. Properties come in two categories; Writables and Readables. A writable value can be changed either using a setter or by directly modifying the property. JavaFX will handle the event processing and make sure every component that depends on the property will be notified. A readable value has methods that allow you to receive notifications when the value changes.

Example:
// Read- and writable
StringProperty name = new SimpleStringProperty("Emil"); 
// Only readable
ObservableBooleanValue nameIsEmpty = name.isEmpty();

2. Binding values

When you have a writable and a readable value, you can start defining rules for how these values relate. A writable property can be bound to a readable property so that its value will always match the readable one. Bindings are not immediate, but they will be resolved before the values are observed (see what I did there). Bindings can be unidirectional or bidirectional. Of course, if they are bidirectional, both properties will need to be writable.

Example:
TextField fieldA = new TextField();
TextField fieldB = new TextField();
fieldA.prefWidthProperty().bind(fieldB.widthProperty());

3. Observable Lists

Properties are not the only thing that can be observed. The members of a list can also be observed if the list is wrapped in an ObservableList. The reaction model of the ObservableList is quite advanced. Not only can you receive a notification when the list is modified, you can also see exactly how the list was changed.

Example:

List<String> otherList = Arrays.asList("foo", "bar", "bar");
ObservableList<String> list = FXCollections.observableList(otherList);

list.addListener((ListChangeListener.Change<? extends String> change) -> {
    System.out.println("Received event.");
    while (change.next()) {
        if (change.wasAdded()) {
            System.out.println(
                "Items " + change.getAddedSubList() + " was added.");
        }

        if (change.wasRemoved()) {
            System.out.println(
                "Items " + change.getRemoved() + " was removed.");
        }
    }
});

System.out.println("Old list: " + list);
list.set(1, "foo");
System.out.println("New list: " + list);

The output from the above is:

Old list: [foo, bar, bar]
Received event.
Items [foo] was added.
Items [bar] was removed.
New list: [foo, foo, bar]

As you can see, the set operation only created one event.

4. StringConverter

Sometimes, you will find that you don’t have the exact value in a component as you need to create a binding. A typical example of this is that you have a StringProperty with the path that you have gotten from a TextField. If you want an observable property with this value expressed as a Path, you will need to create a StringConverter for that.

Example:
TextField fileLocation = new TextField();
StringProperty location = fileLocation.textProperty();
Property<Path> path = new SimpleObjectProperty<>();

Bindings.bindBidirectional(location, path, new StringConverter<Path>() {
    @Override
    public String toString(Path path) {
        return path.toString();
    }

    @Override
    public Path fromString(String string) {
        return Paths.get(string);
    }
});

The object property is not bound bidirectionally to the textfield value.

5. Expressions

Using the Bindings-class shown before you can create all kinds of expressions. Say that you have two textfields that the user can enter information into. You now want to define a read-only field that always contains a string that if the two string lengths are equal, expresses the character by character mix between the two. If the lengths are not equal, a helping message should be shown instead.

Example:
TextField first  = new TextField();
TextField second = new TextField();
TextField mix    = new TextField();

mix.textProperty().bind(
    Bindings.when(
        first.lengthProperty().isEqualTo(second.lengthProperty())
    ).then(Bindings.createStringBinding(
        () -> {
            int length        = first.lengthProperty().get();
            String firstText  = first.textProperty().get();
            String secondText = second.textProperty().get();
            char[] result     = new char[length * 2];

            for (int i = 0; i < length; i++) {
                result[i * 2]     = firstText.charAt(i);
                result[i * 2 + 1] = secondText.charAt(i);
            }

            return new String(result);
        }, 
        first.textProperty(),
        second.textProperty()
    )).otherwise("Please enter two strings of exactly the same length.")
);

Conclusion

These were only a handful of the many features of JavaFX. Hopefully you can find many more creative ways of utilizing the event system!

Friday, January 15, 2016

The Best of Both Worlds

Type-Safe Views using Abstract Document Pattern

NARNIA.png

How do you organize your objects? In this article I will introduce a pattern for organizing so called noun-classes in your system in a untyped way and then expose typed views of your data using traits. This makes it possible to get the flexibility of an untyped language like JavaScript in a typed language like Java, with only a small sacrifice.

Every configuration the user does in your UI, every selection in a form need to be stored someplace accessible from your application. It needs to be stored in a format that can be operated on. The school-book example of this would be to define classes for every noun in your system, with getters and setters for the fields that they contain. The somewhat more serious way of doing the school-book model would be to define enterprise beans for every noun and process them using annotations. It might look something like this:

There are limitations to these static models. As your system evolves, you will need to add more fields, change the relations between components and maybe create additional implementations for different purposes. You know the story. Suddenly, static components for every noun isn’t as fun anymore. So then you start looking at other developers. How do they solve this? In untyped languages like JavaScript, you can get around this by using Maps. Information about a component can be stored as key-value pairs. If one subsystem need to store an additional field, it can do that, without defining the field beforehand.


var myCar = {model: "Tesla", color: "Black"};
myCar.price = 80000; // A new field is defined on-the-fly

It accelerates development, but at the same time comes with a great cost. You lose type-safety! The nightmare of every true Java developer. It is also more difficult to test and maintain as you have no structure for using the component. In a recent refactor we did at Speedment, we faced these issues of static versus dynamic design and came up with a solution called the Abstract Document Pattern.

Abstract Document Pattern

A Document in this model is similar to a Map in JavaScript. It contains a number of key-value pairs where the type of the value is unspecified. On top of this un-typed abstract document is a number of Traits, micro-classes that express a specific property of a class. The traits have typed methods for retrieving the specific value they represent. The noun classes are simply a union of different traits on top of an abstract base implementation of the original document interface. This can be done since a class can inherit from multiple interfaces.

Implementation

Let’s look at the source for some these components.

Document.java
public interface Document {
    Object put(String key, Object value);

    Object get(String key);

    <T> Stream<T> children(
            String key,
            Function<Map<String, Object>, T> constructor
    );
}
BaseDocument.java
public abstract class BaseDocument implements Document {

    private final Map<String, Object> entries;

    protected BaseDocument(Map<String, Object> entries) {
        this.entries = requireNonNull(entries);
    }

    @Override
    public final Object put(String key, Object value) {
        return entries.put(key, value);
    }

    @Override
    public final Object get(String key) {
        return entries.get(key);
    }

    @Override
    public final <T> Stream<T> children(
            String key,
            Function<Map<String, Object>, T> constructor) {

        final List<Map<String, Object>> children = 
            (List<Map<String, Object>>) get(key);

        return children == null
                    ? Stream.empty()
                    : children.stream().map(constructor);
    }
}
HasPrice.java
public interface HasPrice extends Document {

    final String PRICE = "price";

    default OptionalInt getPrice() {
        // Use method get() inherited from Document
        final Number num = (Number) get(PRICE); 
        return num == null
            ? OptionalInt.empty()
            : OptionalInt.of(num.intValue());
    }
}

Here we only expose the getter for price, but of course you could implement a setter in the same way. The values are always modifiable through the put()-method, but then you face the risk of setting a value to a different type than the getter expects.

Car.java
public final class Car extends BaseDocument
        implements HasColor, HasModel, HasPrice {

    public Car(Map<String, Object> entries) {
        super(entries);
    }

}

As you can see, the final noun class is minimal, but you can still access the color, model and price fields using typed getters. Adding a new value to a component is as easy as putting it into the map, but it is not exposed unless it is part of an interface. This model also works with hierarchical components. Let’s take a look at how a HasWheels-trait would look.

HasWheels.java
public interface HasWheels extends Document {
    final String WHEELS = "wheels";

    Stream<Wheel> wheels() {
        return children(WHEELS, Wheel::new);
    }
}

It is as easy as that! We take advantage of the fact that in Java 8 you can refer to the constructor of an object as a method reference. In this case, the constructor of the Wheel-class takes only one parameter, a Map<String, Object>. That means that we can refer to it as a Function<Map<String, Object>, Wheel>.

Conclusion

There are both advantages and of course disadvantages with this pattern. The document structure is easy to expand and build upon as your system grows. Different subsystems can expose different data through the trait-interfaces. The same map can be viewed as different types depending on which constructor was used to generate the view. Another advantage is that the whole object hierarchy exists in one single Map which means that it is easy to serialize and deserialize using existing libraries, for example Google’s gson tool. If you want the data to be immutable, you can simply wrap the inner map in an unmodifiableMap() in the constructor and the whole hierarchy will be secured.

One disadvantage is that it is less secure than a regular beans-structure. A component can be modified from multiple places through multiple interfaces which might make the code less testable. Therefore you should weigh the advantages against the disadvantages before implementing this pattern on a larger scale.

If you want to see a real-world example of the Abstract Document Pattern in action, take a look at the source code of the Speedment project where it manages all the metadata about the users’ databases.