Should interfaces be placed in a separate package?

Viewed 63928

I'm new to a team working on a rather large project, with lots of components and dependencies. For every component, there's an interfaces package where the exposed interfaces for that component are placed. Is this a good practice?

My usual practice has always been interfaces and implementations go in the same package.

14 Answers

Placing both the interface and the implementation is common place, and doesn't seem to be a problem.

Take for example the Java API -- most classes have both interfaces and their implementations included in the same package.

Take for example the java.util package:

It contains the interfaces such as Set, Map, List, while also having the implementations such as HashSet, HashMap and ArrayList.

Furthermore, the Javadocs are designed to work well in those conditions, as it separates the documentation into the Interfaces and Classes views when displaying the contents of the package.

Having packages only for interfaces may actually be a little bit excessive, unless there are enormous numbers of interfaces. But separating the interfaces into their own packages just for the sake of doing so sounds like bad practice.

If differentiating the name of a interface from an implementation is necessary, one could have a naming convention to make interfaces easier to identify:

  • Prefix the interface name with an I. This approach is taken with the interfaces in the .NET framework. It would be fairly easy to tell that IList is an interface for a list.

  • Use the -able suffix. This approach is seen often in the Java API, such as Comparable, Iterable, and Serializable to name a few.

For any language, putting them together in the same package is fine. The important thing is what's exposed to the outside world, and how it looks from outside. Nobody's going to know or care if the implementation is in that same package or not.

Let's look at this particular instance.

If you have all public things in one package, and private things in another package that is not publicly exposed, the client of the library sees one package. If you move the private things to the package with the publicly exposed things, but do not expose them from within the package, the client sees exactly the same thing.

Thus, this has the smell of a rule with no good reason: it's making a decision based on something being publicly visible without that decision having any effect on what's publicly visible.

That said, if in any particular instance it seems like a good idea to split the interface and implementation in to separate packages, go right ahead and do that. Reasons for doing this that come to mind are that the package is huge, or you have an alternate implementation you might want to link in instead of the standard one.

In many frameworks, such as OSGi, you almost have to. I think this promotes looser coupling, at the package instead of the jar level.

One argument for putting interfaces in different packages is that it is easier to create 'api' jars that can be distributed to consumers of your product or service. It's perfectly possible to do this with interfaces and implementations together, but simpler to script if they are in different packages.

Yes, it's a very good practice, because it allows you to publish the interface without publishing your specific implementation. That said, if you have no need to publish external interfaces, there's no problem with putting the interface definitions in the same package as the implementation.

We do this where I work (ie: put interface in one package and implementation in another) and the main advantage we get out of this is we can easily swap between implementations.

I haven't much Java experience, but I like to do this as a good practice in C#/.NET because it allows for future expansion where the assemblies with the concrete classes which implement the interfaces may not be distributed all the way down to the client because they are proxied by a middleman factory or across the wire in a web service scenario.

I prefer them in the same package. Feels pointless to create a package specifically for interfaces. This is especially redundant for teams that simply love their interface prefixes and suffixes (e.g. the "I", and "Impl" for Java).

If there's a needs to publish a set of interfaces as public API, it makes more sense to keep them in an entirely separate project and create project dependencies instead. But it all boils down to preference and convenience of the situation I suppose.

Put them in packages that reflect your projects. It is fine and common to put interfaces and implementations together if they're part of the same project, but if you're writing an API, then someone else would likely be choosing a package name relevant to their project.

In general, if it's for the same project, I don't see any benefit in keeping the interfaces in a separate package from their impls. If it's getting cluttered, there may be other package naming issues, irrespective of the interface arrangement.

Related