pveentjer
pveentjer

Reputation: 11402

Prevent Internals leaking into API

I'm looking for different ways to prevent internals leaking into an API. This is a huge problem because once these internals leak into the API; you can run either into unexpected incompatibility issues or into frozen internals.

One of the simplest ways to do so is just make use of different Maven modules; one module with API and one module with implementation. This way it is impossible to expose the implementation from the API.

Unfortunately not everyone agrees this is the best approach; But are there other alternatives? E.g using checkstyle or other 'architecture checking' tools?

PS: Java 9 for us is not usable, since we are about to upgrade to Java 8 and this will be the lowest supporting version for quite some time to come.

Upvotes: 3

Views: 347

Answers (4)

ToYonos
ToYonos

Reputation: 16843

Here is a good start : http://wiki.netbeans.org/API_Design

Key point : Do not expose more than you want Obviously the less of the implementation is expressed in the API, the more flexibility one can have in future. There are some tricks that one can use to hide the implementation, but still deliver the desired functionality

I think you don't need any checkstyle or anything like that, just a good old solid design and architecture should be enough. Polymorphism is all you need here.

One of the simplest ways to do so is just make use of different Maven modules; one module with API and one module with implementation. This way it is impossible to expose the implementation from the API.

Yes, I totally agree, hide as much as possible, separate your interface in a standalone project.

Upvotes: 0

Brian
Brian

Reputation: 902

One alternative is to have one module (Jar file) for API and implementation (but then again, is it an API or just any kind of library?). Inside one separates classes and interfaces by using packages, e.g. com.acme.stuff.api and com.acme.stuff.impl. It is important to make classes inside the latter package protected or just package-protected. Not only does the package name show the consuming developer "hey, this is the implementation", it is also not possible to use anything inside (let's omit reflections at this point for the sake of simplicity).

But again: This is against the idea of an API, because usually the implementation can be changed. With this approach one cannot separate API from implementation, because both are inside the same module.

If it is only about hiding internals of a library, then this is one (not the one) feasible approach.

And just in case you meant a library instead of an API, which only exposes its "frontend" (by using interfaces or abstract classes and such), use different package names, e.g. com.acme.stuff and com.acme.stuff.internal. The same visibility rules apply of course.

Also: This way one does not need Checkstyle and other burdens.

Upvotes: 0

rompetroll
rompetroll

Reputation: 4799

Following your checkstyle idea, it should be possible to set up rules which examine import statements in source files.

Checkstyle has built-in support for that, specifically the IllegalImport and ImportControl rules.

This of course works best if public and internal classes can be easily separated by package names.

The idea for IllegalImport would be that you configure a TreeWalker in checkstyle which only looks at your API-sources, and which excludes imports from internal packages.

With the ImportControl rule on the other hand you can define very detailed access rules for the whole application/module in a separate XML file.

Upvotes: 1

mikep
mikep

Reputation: 3905

It is standard in Java to define an API using interfaces and implement them using classes. That way you can change the "internals" however you want and nothing changes for the user(s) of the API.

Upvotes: 0

Related Questions