Library Documentation
Welcome to the living documentation of the Sprouts library.
The Sprouts property collections library is a utility library for bridging the gap between modern data oriented programming and classical place oriented programming principles through observable lens properties.
It provides all necessary tools to implement common architectural
design patterns like MVVM, MVI, MVL, specifically for data oriented
programming (immutable value objects, lenses, circular data flow, etc.).
Sprouts was built in conjunction with the SwingTree GUI Framework, which has native support for binding to Sprouts properties.
Although you can use Sprouts properties to build classical (mutable)
property based domain models, we recommended using it as a
tool for binding frontends to value based domain models in your backend.
This is especially useful in GUI programming, where data oriented / functional
programming principles are hard to apply due to the inherently place oriented
nature of GUI components.
Sprouts allows you to create lens based properties that make value object based
view models interoperable with your GUI components or other kinds of views.
This is best achieved using the MVI (Model-View-Intent) and MVL (Model-View-Lens) patterns.
Here an example demonstrating how to create
a set of bindable properties from a basic record based
modelling scenario:
public record Address(
String street, String city, int postalCode
) {
public Address withStreet(String street) {
return new Address(street, city, postalCode);
}
public Address withCity(String city) {
return new Address(street, city, postalCode);
}
public Address withPostalCode(int postalCode) {
return new Address(street, city, postalCode);
}
}
public record Person(
String forename, String surname, Address address
) {
public Person withForename(String forename) {
return new Person(forename, surname, address);
}
public Person withSurname(String surname) {
return new Person(forename, surname, address);
}
public Person withAddress(Address address) {
return new Person(forename, surname, address);
}
}
View:
public final class PersonView {
public static void main(String[] args) {
Person person = new Person("John", "Doe", new Address("Main Street", "Springfield", 12345));
Var<Person> applicationState = Var.of(person);
var view = new PersonView(applicationState);
// show view
}
public PersonView(Var<Person> vm) {
Var<String> forename = vm.zoomTo(Person::forename, Person::withForename);
Var<String> surname = vm.zoomTo(Person::surname, Person::withSurname);
Val<String> fullName = vm.viewAsString( person -> person.forename() + " " + person.surname() );
Var<Address> address = vm.zoomTo(Person::address, Person::withAddress);
Var<String> street = address.zoomTo(Address::street, Address::withStreet);
Var<String> city = address.zoomTo(Address::city, Address::withCity);
Var<Integer> postalCode = address.zoomTo(Address::postalCode, Address::withPostalCode);
// Use mutable properties in the views GUI...
}
}