Gabi und Sascha
Tags - Kategorien : Alle | Berlin | Bücher | Fotografie | Java | Linkhalde | Weichware | Verfassung

Das Testen von private-Methoden unter Java ist nicht immer ganz einfach. Diese kann man entweder nur undirekt testen, was das Schreiben von Unit-Tests erheblich verkompliziert. Oder man verwendet die Reflection API und schaltet die ReflectPermission aus. Wirklich Spass macht auch dieses Vorgehen nicht. Bleibt als Alternative die Möglichkeit die private-Methoden durch protected-Methoden zu ersetzen. Testsysteme können dann von diesen ableiten und diese dann public machen, wenn die Methoden nicht zusätzlich auch noch final sind. Nachteilig ist hier, dass eigentlich für die API nicht wichtige Methoden nach aussen sichtbar sind.

Die Lösung liegt im anlegen von 2 Codeebenen. Eine für den eigentlichen Quellcode und eine für den Testcode, der später nicht mit ausgeliefert wird. In beiden Ebenen wird die gleiche Packagestruktur aufgebaut. Beiden Ebenen werden nacheinander in unterschiedliche Binärverzeichnisse compiliert, wobei die Testebene als letztes dran kommt. Über den Classloader werden jetzt beide Ebenen wieder zusammen geführt und die Testcases ausgeführt. private-Methoden lassen sich auch so nicht einfach testen. Da aber Packagestrukturen im allgemeinen nicht ausufernd komplex sind ist es durchaus zulässig alle private-Methoden als package-private, also ohne Sichtbarkeitsmodifikator, zu implementieren. Die Testklassen können jetzt auf diese Methoden ohne Umwege zugreifen und deren Verhalten testen.

Mit diesem Kniff gibt man einen kleinen Teil des Geheimnisprinzips des OO-Paradigmas preis, erhält im Gegenzug aber übersichtlichere und höherwertige Tests und damit bessere Software. Ich gehe jetzt seit mehreren Jahren bei der Entwicklung so vor und habe noch keine Nachteile feststellen können.

Im Prinzip ist der private-Sichtbarkeitmodifikator unter Java überflüssig.


Ebenso überflüssig ist auch der protected-Sichtbarkeitsmodifikator. Alle Subklassen können mit diesem Modifikator versehene Eigenschaften sehen. Die Ausnahme sind jedoch Klassen, die sich im selben Paket befinden. Auch sie können diese Eigenschaften sehen. Somit ist die mit protected versehene Eigenschaft fast public und somit überflüssig. Das bedeutet, dass bei einer API protected-Members immer unterstützt werden müssen. Ausserdem repräsentiert dieses Member ein offens Detail einer eigentlich versteckten Implementierung.

Schlussfolgerung: protected ist nicht notwendig und verkompliziert bei Anwendung das Design.

Das sehe ich etwas anders. protected bei Feldern ist nicht sinnvoll, weil hier das Geheimnisprinzip durchbrochen wird. Der Zugriff hat über Methoden zu erfolgen. Deswegen darf man Felder auch nicht public machen.

Im Sinne der Vererbung, die man allerdings immer sehr vorsichtig einsetzen sollte, macht protected schon erheblich mehr Sinn. Denn damit erlaube ich eben ableitenden Klassen, und eben nur diesen, dass sie bewusst hier ansetzen können, um die Funktionalität anzupassen. Deswegen macht protected in Java mehr Sinn als private und es sollte nicht darauf verzichtet werden. Allerdings ist der Einsatz der protected Sichtbarkeit sehr vorsichtig einzusetzen. Im Zweifel sollte darauf verzichtet werden.