Should interfaces be placed in a separate package? [closed]
Solution 1:
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 thatIList
is an interface for a list.Use the -
able
suffix. This approach is seen often in the Java API, such asComparable
,Iterable
, andSerializable
to name a few.
Solution 2:
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.
Solution 3:
In many frameworks, such as OSGi, you almost have to. I think this promotes looser coupling, at the package instead of the jar level.
Solution 4:
The book Practical Software Engineering: A Case-Study Approach advocates for putting interfaces in seperate projects/packages.
The PCMEF+ architecture which the book talks about has the following principles:
- Downward Dependency Principle (DDP)
- Upward Notification Principle (UNP)
- Neighbor Communication Principle (NCP)
- Explicit Association Principle (EAP)
- Cycle Elimination Principle (CEP)
- Class Naming Principle (CNP)
- Acquaintance Package Principle (APP)
The description of principle #3 and #7 explain why it is a good idea:
The Neighbor Communication Principle demands that a package can only communicate directly with its neighbor package. This principle ensures that the system does not disintegrate to an incompressible network of intercommunicating objects. To enforce this principle, message passing between non-neighboring objects uses delegation (Section 9.1.5.1). In more complex scenarios, acquaintance package (Section 9.1.8.2) can be used to group interfaces to assist in collaboration that engages distant packages.
The Acquaintance Package Principle is the consequence of the Neighbor Communication Principle. The acquaintance package consists of interfaces that an object passes, instead of concrete objects, in arguments to method calls. The interfaces can be implemented in any PCMEF package. This effectively allows communication between non-neighboring packages while centralizing dependency management to a single acquaintance package. The need for acquaintance package was explained in Section 9.1.8.2 and is discussed again next in PCMEF context.
See this link: http://comp.mq.edu.au/books/pse/about_book/Ch9.pdf
Solution 5:
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.