samedi 23 janvier 2016

Java (Android) library project - How to design optional modules?

I am creating an Android (Java) based library project (JAR) where there are -

  1. Core features
  2. Optional features

Now due to size constraints, I have to break this JAR into collection of JARs, where user of this library will have the flexibility to include optional JARs. At the same time, the requirement is to provide a single interface to the user, using which they should be able to call both core and optional APIs. To achieve this, I have two solutions in mind -

Solution-1 Have class implementation for the interface in core library, where APIs related to core feature are implemented here, but API for optional features will be invoked from here using reflection, so that if class found, indicates that optional library is included otherwise not.

APIInterface.java

public interface APIInterface {
    public void coreMethod();
    public void optionalMethod();
}

CoreClass.java

public class CoreClass implements APIInterface {
  public void coreMethod() {
    // implementation
  }
  public void optionalMethod() {
    // use reflection to access optional method from OptionalClass
  }
}

OptionalClass.java

public class OptionalClass {
  public void optionalMethod() {
    // implementation
  }
}

Pros - Here only optional includes core (for core services), core doesn't include optional. So no circular dependency.
Cons - Reflection is used

Solution-2 To avoid reflection mentioned in solution-1, create two versions of optional libraries. First with full implementation and second with empty implementation (only wrappers). Users will have to include mandatorily either one of them, depends on whether user needs optional features or not. With this, the dependency will be inversed. So, core will include the optional library by default, and will be able to call the API from optional library without reflection.

APIInterface.java

public interface APIInterface {
    public void coreMethod();
    public void optionalMethod();
}

CoreClass.java

public class CoreClass implements APIInterface {
  public void coreMethod() {
    // implementation
  }
  public void optionalMethod() {
    new OptionalClass().optionalMethod();
  }
}

OptionalClass.java // full implementation

public class OptionalClass {
  public void optionalMethod() {
    new CoreClass().utilityMethod(); // or super.utilityMethod();
    // optional implementation
  }
}

OptionalClass.java // empty implementation

public class OptionalClass {
  public void optionalMethod() {
    // do nothing
  }
}

Pros - No reflection
Cons - 1. There is a circular dependency on core and optional, since core includes optional to invoke optional API and optional includes core to use core utilities and services.
2. User will have to mandatorily include optional JARs (either full or empty implementation)

Which solution you recommend or any other better solution? Please suggest.





Aucun commentaire:

Enregistrer un commentaire