An implementation detail is an internal choice a component uses to do its work. Clients should depend on the smallest stable interface they need, not on internal classes, field names, framework behavior, or other details likely to change. This is information hiding: separate what is likely to change from what is not, so components can evolve independently. section 4.2 section 7.5
Coupling to details turns a local refactoring into a wider maintenance problem. A changed internal class can break dependent modules; knowledge of those dependencies can also discourage a team from improving its own code. Hiding every detail is impossible, so the practical design task is to choose deliberately what to expose, conceal volatile behavior behind a stable abstraction, and reveal no more information than clients require. section 4.2 section 7.3.2
Treat implementation details as a dependency-management boundary:
- Expose a clear API or interface rather than internal classes and packages. section 7.3.2 section 7.5
- Ask whether a client would be affected by an internal refactoring and whether the exposed code changes frequently. section 4.2
- Isolate infrastructure-specific code instead of scattering it through the codebase. section 6.1.2
- Ignore leaked internals when possible, and raise the leak with the owning team rather than building a dependency on it. section 7.3.1
Indirect framework leakage
An interface can hide Hibernate while a Hibernate-managed entity still leaks behavior: closing a transaction may persist it automatically, and a getter may trigger database queries. When that behavior is undesirable in domain code, add a layer whose contract prevents Hibernate from managing the entities used there. The framework detail remains understood by developers, but is no longer allowed to control unrelated code. section 6.3.2
Internal names are not an API
Depending on an internal class is fragile; depending on its field names is even more so. IDEs coupled to field names in JUnit 4 could stop working after a rename. Document public packages and APIs, and enforce boundaries with tools such as ArchUnit or JPMS so accidental internal dependencies are caught early. section 7.3.2
Use the module-boundary diagram to distinguish a supported module interface from internal classes that neighboring modules should not consume. section 7.3.2
Implementation details should be hidden from code that does not need them, not hidden from developers making design decisions. Infrastructure and imperfect module boundaries still require informed judgment: extra isolation adds effort, and a visible leak may have a valid reason. Favor the level of concealment that limits future change impact without adding unnecessary elegance. section 6.3.2 section 7.3.1


