I'm building a library package, which has an interface PropTransformer
which will be implemented by 30+ classes. I'm taking one such class here say ShapeTransformer
public interface PropTransformer<T, R> {
R transform(T t);
T reverseTransform(R r);
}
public class ShapeTransformer implements PropTransformer<List<String>, Set<String>> {
@Override
public Set<String> transform(final List<String> list) {
// transform code
}
@Override
public List<String> reverseTransform(final Set<String> set) {
// reverseTransform code
}
}
This library's classes methods can be invoked using new
operator obviously, but since a lot of transformations can be done on user side so a lot of instantiation will appear bloated. Something like:
new ShapeTransformer().transform(...);
new TemperatureTransformer().transform(...);
...
I could think of creating a utility class Transformer
which would provide a direct invocation for transformers, like
public class Transformer<T, R> {
private static ShapeTransformer shapeTransformer = new CompatibleDevicesTransformer();
public static Set<String> shapeTransform(final List<String> list) {
return shapeTransformer.transform(list);
}
public static List<String> shapeReverseTransform(final Set<String> set) {
return shapeTransformer.reverseTransform(set);
}
}
Library user can then use it like
Transformer.shapeTransform(...)
Problems with this approach:
PropTransformer
.Transformer
classIs there a cleaner/better way to accomplish this? Through method reference(s) and/or functional interface(s), if possible?
Something like
Transformer t = new Transformer();
t.transform(ShapeTransformer::transform);
t.transform(TemperatureTransformer::transform);
(^ this is just to provide a peek into what I'm looking for. I'm not necessarily suggesting to make the transformers method static)
PropTransformer
is not a functional interface as it contains more than 1 abstract method. So, you can't implement and call these methods using lamda expression.
You can split PropTransformer
into functional interfaces PropTransformer
and PropReverseTransformer.
But decision should be based on how PropTransformer
fit into overall design.
To further reduce boilerplate code at client side, you can create PropTransformerFactory
- a utility to create PropTransformer
implementations.
Pseudo Code:
public class PropTransformerFactory {
public static PropTransformer createShapeTransformer() {
return new ShapeTransformer();
}
public static PropTransformer createTemperatureTransformer() {
return new TemperatureTransformer();
}
}