views:

51

answers:

1

Put them all in one separate folder structure or along with classes which implements them ?

+2  A: 

You should never put interfaces together with the classes that implement them (unless those classes fulfull the requirements below). Doing that will introduce a tight coupling between the interface and the implementer, and you will not be able to create other implementations of the interface without simulataneously referencing the implementer.

You basically have two options:

  • Put the interfaces together with the classes consuming them. This still creates a tight coupling, but this coupling is less problematic, as the consumers often live in a library that provides related types. In this case, if you have implementers in this library, they can implement the interfaces without introducing any additional coupling.
  • For the ultimate in loose coupling, put the interfaces in a separate library. This gives you greater flexibility, but may also requires a bit extra work.
Mark Seemann
@Mark Seemann - I don't get your point about tight coupling. If e.g. in Java I have a public interface and its package-private default implementation in the same package, how is this setup coupling the two? I also miss the "requirements below" you are referring to.
Péter Török
@Péter Török: To implement the interface you must have a reference to it. If the implementer is in the same library, you drag along that implementer. In some cases it may not seem to matter, but if the implementer is big or references other libraries that are implementation-specific, the implementation leaks through. Even when this isn't the case, it would still be wrong because it would force the consumer to have a reference to the implementer instead of just the interface, and thus be tightly coupled to it.
Mark Seemann
@Péter Török: The only case when the implemter can be in the same library as the interface is when that library is also where the consumer is defined. In this case, the interface may just be a Seam, while a well-defined default implementation is already in place. In this case the coupling goes both ways, but any new implementer will conceptually only have to reference the interface, because the fact that one or more implementations are defined in the same library is incidental (they may even not be externally visible).
Mark Seemann
@Mark Seemann I see, thanks. I generally agree, although I consider the case when one publishes the interface as part of a library the exception rather than the norm. Separation still doesn't hurt though (except that it complicates the package hierarchy a bit).
Péter Török