Factory which is not dependant on implementation

642 views Asked by At

I have an api which has some base implementations. I have a factory which gives the instances of that api to the clients.

I want to change my factory to make it more generic so, if a new implementation of the api will be generated and its jar file will be put in classpath, the factory will understand it and any changes wouldn't be needed.

2

There are 2 answers

1
Joop Eggen On BEST ANSWER

Use the java SPI, Service Provider Interface.

  • API jar - Provide one single interface.
  • Provider jar - Provide implementations in jars. You can even put several implementations in a jar. In a text file META-INF/services/my.package.MyInterface one lists implementing class(es).
  • Application - In the application the implementing jar should not be needed for compilation: in maven scope runtime.

The service discovery happens with a ServiceLoader<T>:

public static void main(String[] args) {
    ServiceLoader<MyInterface> loader = ServiceLoader.load(MyInterface.class);
    for (MyInterface api : loader) {
        api. ...
    }
    // Or take the first implementation:
    MyInterface api = loader.iterator().next();
}

You could provide a class in the API jar with a static function for that discovery mechanism.

Advantages:

  • Separation
  • Several implementations possible
  • Selection of implementation can be done dynamically

Example of jars

  • xxx-api.jar
    • my/package/MyInterface.class
  • xxx-first-impl.jar
    • META-INF/services/my.package.MyInterface
      • my.package.impl.MyImpl1
    • my/package/impl/MyImpl1.class
      • public class MyImpl1 implements MyInterface { ... }
  • myapp1.jar
7
kervin On

If you'd like to start with theory. Please read about Dependency inversion principle.

In object-oriented programming, the dependency inversion principle refers to a specific form of decoupling software modules. When following this principle, the conventional dependency relationships established from high-level, policy-setting modules to low-level, dependency modules are inverted (i.e. reversed), thus rendering high-level modules independent of the low-level module implementation details.

A. High-level modules should not depend on low-level modules. Both should depend on abstractions.

B. Abstractions should not depend on details. Details should depend on abstractions.

The principle inverts the way some people may think about object-oriented design, dictating that both high- and low-level objects must depend on the same abstraction.

Dependency Injection Library

As for specific implementations, you have many in Java. Specifically for the Dependency Injection approach. Spring Framework obviously comes to mind. But you can also look at Java EE Context and Dependency Injection.

Interface Injection

You can also...

  1. Load the Jars manually : How should I load Jars dynamically at runtime?
  2. Use Interface Injection : Spring interface injection example ( This title says Spring, but the answers show no Spring is needed for Interface Injection )