Patterns

Beneath others, JTools uses the following patterns:

Helper Pattern

Motivation

In many cases it is desired to deal with immutuable objects. To construct those objects - maybe in reflective environments (Java-Beans, Ant, DAO ...) - we use helper classes.

Design

If we have an immutuable class foo with one property Bar:
public class Foo {
    private final int bar;
    public Foo(int bar) {
        this.bar=bar;
    }
    public int getBar() {
        return bar;
    }
 }
The appropriate helper class would look like this:
public class FooHelper {
    private int bar;
    public void setBar(int bar) {
        this.bar=bar;
    }
    public Foo toFoo() {
        return new Foo(bar);
    }
 }

Filter Pattern

Motivation

Design

Mapper Pattern

Motivation

Design

Visitor Pattern

Motivation

The Visitor Pattern is used to move functionality out of the object instance and to avoid switch-case-statements.

Design

Jtools uses a little modified version of the standard visitor pattern to allow stateless use of visitors in most cases. If there is an interface Sample with two characteristic values Foo and Bar, the appropriate Pattern usage would be
//Sample interface
public interface Sample {
    //accept method
    <R, D> R accept(SampleVisitor<R, D> visitor, D... data);
}
//Implementation Foo
public class Foo implements Sample {
    //accept method calls visitFoo
    public <R, D> R accept(SampleVisitor<R, D> visitor, D... data) {
        return visitFoo(visitor, data);
    }
}
//Implementation Bar
public class Bar implements Sample {
    //accept method calls visitBar
    public <R, D> R accept(SampleVisitor<R, D> visitor, D... data) {
        return visitBar(visitor, data);
    }
}
//The Visitor interface for Sample
public interface SampleVisitor<R, D> {
    //callback hook for Foo
    R visitFoo(Foo foo, D... data);
    //callback hook for Bar
    R visitBar(Bar bar, D... data);
    //callback hook for custom Sample characteristics
    R visitCustomSample(Sample sample, D... data);
}
//The standard implementation for the visitor
public class SimpleSampleVisitor<R, D> implements SampleVisitor<R, D> {
    public R visitFoo(Foo foo, D... data) {
        return visitDefinedSample(foo, data);
    }
    public R visitBar(Bar bar, D... data) {
        return visitDefinedSample(bar, data);
    }
    protected R visitDefinedSample(Sample sample, D... data)  {
        return visitSample(sample, data);
    }
    public R visitCustomSample(Sample sample, D... data)  {
        return visitSample(sample, data);
    }
    protected R visit(Sample sample, D... data) {
        return null;
    }
}
A method can now define a singleton visitor instance to calculate values.
public class SampleUtils {
    private static class AdjustVisitor extends SampleVisitor<Double, Boolean> {
        public Double visitFoo(Foo foo, Boolean... data) {
            //using autoboxing
            return data[0] ? 2.0 : 2.5 ;
        }
        public Double visitBar(Bar bar, Boolean... data) {
            //using autoboxing
            return data[0] ? 1.1 : 0.5;
        }
        protected Double visit(Sample sample, Boolean... data) {
            throw new RuntimeException("unexpected Sample implementation "+sample);
        }
    }
    private static AdjustVisitor adjustVisitor = new AdjustVisitor();

    public static Double multiply(Sample sample, boolean extended) {
        return sample.accept(adjustVisitor, extended ? Boolean.TRUE : Boolean.FALSE);
    }
}