views:

603

answers:

9

i'm new to a team working on a rather large project, lots of components, dependencies. for every component, there's an 'interfaces' package where the 'exposed' interfaces for that component is placed. is this a good practise?

my usual practise has always been interfaces and implementations in same package.

was wondering what's the stackoverflow community's thoughts on this...

A: 

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.

McWafflestix
Maybe if you are defining interfaces for the JCP or something this makes good sense, but if you are producing multiple concrete implementations of these interfaces for your project then it seems like an unnecessary burden to package the interfaces separately.
Brian Reiter
It's not much of a burden, in any event...
McWafflestix
-1 Yes, it is. It makes it unnecessarily hard to find the implementations and separates things that belong together.
Michael Borgwardt
And not publishing the implementations is a completely different matter that can be done by making them package-private - and can NOT be done by placing them in a separate package. There is no such thing as a non-public package.
Michael Borgwardt
Moreover, it sounds like making all the interfaces unnecessarily public.
Adeel Ansari
So what's with all the downvotes on this accepted answer?
McWafflestix
+8  A: 

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 publicly exposed package, 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 publicaly visible without that decision having any effect on what's publicly visible.

Curt Sampson
+1  A: 

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.

hhafez
How does it help you switch the implemenations?
Janusz
see the answer by Cameron Pope, it is exactly the reason we are doing it here
hhafez
+1  A: 

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.

Jesse C. Slicer
+3  A: 

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.

Cameron Pope
You can have the API project separate (being a separate distributable) and that still does not stop interfaces and implementation being in the same package. A bit like you have unit tests in the same package as tested classes but still in a separate build artifact. Jars and packages are pretty much orthogonal in Java.
George
+9  A: 

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.

coobird
+1 although I wouldn't recommend the I* naming convention unless you're in the .NETverse, and even then only for consistency
CurtainDog
I've used this convention in java code and I've found it useful .... YMMV
hhafez
It also seems to be used a lot in the Eclipse ecosystem.
Simon Nickerson
A: 

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.

Rog
A: 

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

javamonkey79
A: 

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.

aberrant80