0

I am looking for a way to properly organize interfaces and implementations in Java 11 modular project.

Considering the simplest case: there is an interface and its multiple implementations. The intention is to expose only this interface and its factory methods as the module API.

MyInterface.java

public interface MyInterface {

  String action(String input);

  //--- factory methods

  static MyInterface createSimple(Object argument){
     return new MySimpleImpl(argument);
  }    

  static MyInterface createComplex(Object a, Object b){
     return new MyComplexImpl(a,b);
  }
}

MySimpleImpl.java

class MySimpleImpl implements MyInterface { ... }

MyComplexImpl.java

class MyComplexImpl implements MyInterface { ... }

Suppose the root package is org.company.myproject.

So module-info.java contains only one export: exports org.company.myproject;


I see several ways to organize the code, for instance the obvious are:

Version 1: Put implementations into a nested package and make them public.

Version 2: Put implementations into the root package and keep them package-private.

At the moment I cannot prefer any of the versions, because the first forces me to break visibility contracts inside the module itself, and the second pollutes the root package making its intentions vague.

Please, help me to understand how to precisely express my intentions for the module's classes visibility inside and outside the module both. Probably, there are best practices for this situation.

diziaq
  • 6,881
  • 16
  • 54
  • 96
  • What is the purpose of the *visibility contracts inside the module itself*? Are they even necessary? If so, wouldn't it make sence to split your module into multiple modules? – qutax Apr 12 '20 at 12:32
  • @qutax The purpose is related to the very existence of keywords `public`, `private`, `protected` - encapsulation and declaration of usage intentions in code. If module has several packages inside (and it is usual, because to make something sufficient you need more that one package), it would be usable to avoid unnecessary exposition of everything to everyone. – diziaq Apr 12 '20 at 15:43
  • I am well aware of the general purpose of encapsulation. My question targeted the purpose of your special case. If you could provide a more detailed example (or maybe the complete code in a public repository, e.g., on Github), then I — or someone else — might be able to understand the concrete problem you're facing and give an answer to your question. For example, what is the purpose of `MyInterface`? It looks like a code smell to me that it's aware of its implementations. Maybe you could make use of the ServiceLoader API for instantiating them instead? – qutax Apr 23 '20 at 14:52

0 Answers0