Blog

Halten Sie Ihre Implementierungen verborgen

Lars Vonk

Aktualisiert Oktober 23, 2025
2 Minuten

Bei den meisten Java-Anwendungen, an denen ich in den letzten Jahren gearbeitet habe, wurde das Prinzip "Program to Interfaces" angewandt. Der Name ist eigentlich selbsterklärend, daher werde ich nicht näher auf das Prinzip eingehen. Da Schnittstellen an sich ziemlich nutzlos sind, brauchen wir mindestens eine Implementierung. In einer typischen Anwendung geschieht dies durch die Definition einer Klasse wie z.B.:

public class JbcAddressDao implements AddressDao {
}

Man könnte sagen, dass hier nichts falsch ist, aber ich denke, dass dieser Code im Widerspruch zu einem der Hauptaspekte der Objektorientierung steht.

Auf der QCON London 2006 erwähnte Martin Fowler, dass einer der wichtigsten Aspekte von OO darin besteht, "Geheimnisse voreinander zu bewahren". Da wir die konkrete Implementierung als öffentlich definiert haben, ist der JdbcAddressDao für die Außenwelt zugänglich. Es gibt nichts, was den Client-Code daran hindert, die Implementierung und nicht die Schnittstelle zu verwenden, so dass wir unser Geheimnis verlieren.Eine Möglichkeit, damit umzugehen, besteht darin, das Konstruktorpaket als privat oder geschützt zu deklarieren. Dadurch wird verhindert, dass der Client-Code einen JdbcAddressDao instanziiert (in einer realen Anwendung erfolgt die Instanziierung wahrscheinlich durch einen Container wie Spring, der mit privaten und geschützten Konstruktoren umgehen kann), aber der Client-Code ist immer noch in der Lage, die Schnittstelle auf die konkrete Implementierung zu übertragen. Das ist zwar eine kleine Verbesserung, aber immer noch zu viel. Um wirklich zu verhindern, dass der Client-Code ein JdbcAddressDao verwendet, sollten wir es als package private deklarieren. Auf diese Weise sind wir sicher, dass niemand außerhalb unseres Pakets unsere Klasse verwenden kann. Dies setzt allerdings voraus, dass sich die Implementierung und die Schnittstelle im selben Paket befinden, was eigentlich sinnvoll ist, da Implementierung und Schnittstelle ohnehin irgendwie miteinander verbunden sind. Container wie Spring können immer noch paketprivate Klassen instanziieren und andernfalls könnten Sie eine Factory definieren, die JdbcAddressDao instanziiert und als AddressDao zurückgibt. Ich denke, wenn wir sorgfältiger darauf achten, welche Zugriffsmodifikatoren wir für Implementierungen verwenden, sind wir in der Lage, robustere Anwendungen zu erstellen und sind dem OO-Himmel einen Schritt näher :-).

Verfasst von

Lars Vonk

Contact

Let’s discuss how we can support your journey.