Are you perhaps looking for SPI?
You could consider defining a factory interface in the API module, then implement this factory interface in the impl module and add the corresponding configuration file for SPI.
// api
public interface Builder {
static Builder create(version) {
ServiceLoader<BuilderFactory> bfs = ServiceLoader.load(BuilderFactory.class);
Iterator<BuilderFactory> itr = bfs.iterator();
if (itr.hasNext()) {
BuilderFactory bf = itr.next();
return bf.create(version);
}
throw new IllegalStateException();
}
}
public interface BuilderFactory {
Builder create(version);
}
// impl
// create [META-INF/services/BuilderFactory's Full classname] in impl module and
// write "DefaultBuilderFactory's full classname"
public class DefaultBuilderFactory implements BuilderFactory {
Builder create(version) {
if (xx) {
return new Builder1;
}
return new Builder2;
}
}