/ezmod

Modular design made easy

Primary LanguageJava

ezMod

Modular design made easy.

True modular design consists in breaking your application into JARs, not just packages. For example:

myapp-api.jar    --> your (well-tested) business logic goes here.
  \_ src/main/java
                  \_ app.UseCase (concrete class)
                  \_ app.SomeRepository (UseCase colaborator injected at runtime)
  \_ src/test/java
                  \_ app.UseCaseTest (unit test your UseCase mocking the colaborator)
                  
myapp-stubs.jar  --> requires myapp-api.jar at compile-time
  \_ src/main/java
                  \_ app.stubs.SomeRepositoryStubs (Simple stubs for agile development)
                  \_ app.Module --> export(app.SomeRepository.class, new app.stubs.SomeRepositoryStubs())
  \_ src/main/resources
                  \_ META-INF/services/com.github.erdanielli.ezmod.AbstractModule --> app.Module
                  
myapp-jdbc.jar   --> requires myapp-api.jar at compile-time (and probably a few JDBC frameworks)
  \_ src/main/java
                  \_ app.jdbc.SomeRepositoryJdbc (Ask the database)
                  \_ app.Module --> export(app.SomeRepository.class, new app.jdbc.SomeRepository())
  \_ src/main/resources
                  \_ META-INF/services/com.github.erdanielli.ezmod.AbstractModule --> app.Module
                  
myapp-client.jar --> bootstrap
  \_ src/main/java
                  \_ app.Main --> new app.UseCase(Injector.getInstance(app.SomeRepository))
  \_ libs
        \_ myapp-api.jar (mandatory)
        \_ EITHER myapp-stubs.jar OR myapp-jdbc.jar (maven profiles to the rescue)

Only 3 steps required:

  1. Create your module
public class ModuleA extends com.github.erdanielli.ezmod.AbstractModule {
  @Override
    protected void configure() {
      export(List.class, new ArrayList());
    }
}
  1. Create the file ...
META-INF/services/com.github.erdanielli.ezmod.AbstractModule

... with your module's (full) class name inside

ModuleA
  1. Inject it anywhere!
public class Main {
  public static void main(String[] args) {
    List emptyArrayList = Injector.getInstance(List.class);
    
    // will throw NoSuchImplementationException
    // Set willFail = Inject.getInstance(Set.class)
   
    Map _null_ = Injector.getInstance(Map.class, true);
  }
}

Versions

0.1 - in progress

  • Multiple modules with cyclic dependency detection;
  • Servlet listener for eager module loading on initialization

0.2 - Coming soon!

  • Support for Spring-based modules
  • (to be defined)