There are several ways how to define a Java fluent API:
- Use static classes/methods + an internal
ThreadLocal
to get the DSL instance - Use setter/getter based methods to chain the API. Personally I don't like the readability of it, e.g. see some Spring Security code examples.
Is there a way to create a Java DSL that is more readable, like fluent methods in Kotlin? For exmaple a Computer
class with Attributes like cpu
/gpu
and nested DSL classes like drives (Note: I want to nest ssd and hdd even further, e.g. define partitions
?
public class Main {
public static void main(String[] arguments) {
Computer computer = Computer.build("Gaming PC").cpu("AMD 5950X").gpu("Lol rly?");
computer.drives(() {
ssd("1TB", "m2");
hdd("10TB", "SATA");
});
computer.print();
}
public static class Computer {
private final Map<String, String> attributes;
private Computer() {
this.attributes = new LinkedHashMap<>();
}
public static Computer build(String name) {
Computer computer = new Computer();
computer.attributes.put("name", name);
return computer;
}
public Computer cpu(String modelName) {
attributes.put("cpu", modelName);
return this;
}
public Computer gpu(String modelName) {
attributes.put("gpu", modelName);
return this;
}
// TODO: Add ssd and hdd. How?
public void print() {
for (Map.Entry<String, String> entry : attributes.entrySet()) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
}
}
}
The example above won't compile. But is there a way to achieve it with regular classes/abstract classes or even interfaces [with default methods?]. Like this:
public class Main {
public static void main(String[] arguments) {
Computer computer = Computer.build("Gaming PC").cpu("AMD 5950X").gpu("Lol rly?");
computer.drives((new DriveManager() {
ssd("1TB", "m2");
hdd("10TB", "SATA");
});
computer.print();
}
public static class DriveManager {
private Computer computer;
public void setComputer(Computer computer) {
this.computer = computer;
}
public void ssd(String size, String interfaceType) {
computer.ssd(size, interfaceType);
}
public void hdd(String size, String interfaceType) {
computer.ssd(size, interfaceType);
}
}
}
But how does one call setComputer
?
Aucun commentaire:
Enregistrer un commentaire