Suche
Be pragmatic, not dogmatic!

"Ein String ist immer ein String, oder doch ein Passwort?"

Joachim Arrasz

Im letzten Teil der Kolumne „Modernes Tooling versus etablierte Best Practices“ ging es um die Einsatzgebiete und den Sinn sogenannter Blueprint-Architekturplänen in Firmen. Blueprints schaffen einheitliche Systemumgebungen, die schnell und effizient pflegbar und wartbar sind. Allerdings schaffen sie auch Entwicklungszyklen, die merklich langsamer und auch weniger agil sind. Man spannt den Bogen also entweder bei den Entwicklern oder aber im Betrieb ein wenig mehr. 😉

In diesem Teil werde ich ein technisches, eigentlich sehr einfaches, aber doch spannendes Thema, welches mich die letzten 10 Jahre immer wieder anstrengt, diskutieren: Vorteile und Nachteile von typsicheren Schnittstellen. 

Noch ein wichtiger Punkt, der unbedingt angemerkt werden muss: Alles was ich hier schreibe ist meine persönliche Meinung und spiegelt auch nur diese wider 🙂 Diskussionen sind herzlich willkommen! Falls sich der eine oder andere Kollege angesprochen fühlt – natürlich ist alles frei erfunden und Ähnlichkeiten sind rein zufällig… 🙂

Ich war beratend bei einem Kunden vor Ort, wo es darum ging, für zukünftige Projekte, welche alle „gleich sein werden“, Entwicklungsstandards zu diskutieren und dann festzulegen. Natürlich bemerkten wir schnell, dass die Projekte eben doch nicht „gleich“ sind. Die Ähnlichkeit innerhalb der Projekte war aus Sicht des Kunden über die selben Usecases gegeben.

Aber seien wir ehrlich, darüber kann ich nahezu jede Webanwendung dieser Welt zu einer anderen „gleich“ setzen. Beispiele: hier „Login, Logout, tbc.“ Kurzum – man verständigte sich schnell darauf, eine Best Practice aus der Architekturwelt anzuwenden, nämlich wichtige Entscheidungen so spät wie möglich zu treffen. Die Diskussion wurde zur Entwicklung eines Developer Guides mit Entwicklungsvorgaben, die nun definiert wurden, genutzt.

Um die wirklich kritischen Dinge zu diskutieren, wurde die Bug Database herangezogen, um eventuell wiederkehrende Fehler ausfindig zu machen, was direkt auch gelang. Es stellte sich heraus, dass etliche Methodensignaturen in etwa wie folgt aussahen:

public String doSomethingUnbelieveable(String withme, String doSomething, String type);

Ich bin mir sicher, jeder Leser hat solche Signaturen schon gesehen, vermutlich auch schon einmal selbst implementiert 🙂 Ich bin mir allerdings nicht mehr so sicher, wie viele Leser solche Dinge auch schon warten, pflegen oder weiter entwickeln mussten. Verallgemeinern wir das Beispiel einmal, um Klarheit über das Problem zu erhalten:

public String doLogin(String arg1, String arg2, String type);

So kennt es vermutlich jeder Entwickler, welcher schon einmal mit Webanwendungen zu tun hatte. Schlechter Stil allemal, das Problem der möglichen Verwechslung ist absolut gegeben. Verbessern wir dieses Beispiel also:

public String doLogin(String username, String password, String type);

Schon viel besser, oder? Nun kam im Team die Frage auf, ob man, ganz im Stil guter objektorientierter Entwicklung, nicht typisieren sollte:

public String doLogin(Username username, Password password, String type);

oder gar:

public String doLogin(Credentials loginCredentials, String type);

Mit einer möglichen Credentials-Implementierung:

public class Credentials {
           public Password password;
           public Username username;
} 

An diesem einfachen Beispiel sieht man, wie viele unterschiedliche Ausprägungen eines einfachen Sachverhalts zustande kommen können. Spannend wäre hier für mich zu wissen, welche Signatur von der lesenden Gemeinschaft denn eingesetzt werden würde 🙂 Was ist wohl am einfachsten zu warten, weiter zu entwickeln und zu pflegen? Was aber ist am schnellsten entwickelt? Was ist der intuitive Weg?

Innerhalb des Projekts kam es zu einer spannenden Diskussion rund um die Nutzung von primitiven Datentypen, die Vorteile, die Nachteile an dieser Stelle. Folgende Entscheidung traf das Team gemeinsam: Es werden Klassen für die Methodenattribute eingeführt, sobald man damit direkt Logik auf dem Attribut kapselt. Ein abstraktes Beispiel hierzu:

public class Password {
           public String password;
           public boolean isValid() {
                  return password.validate();
           }
           private boolean validate() {
                  //snipped some validations
                  return validOrNot;
           }
}

Das Beispiel kann so in der Praxis natürlich nicht wirklich bestehen, aber es zeigt auf einfache Art und Weise auf, wie die Regel gemeint ist, welche das Team aufstellte.

[ header = Seite 2: Meine Meinung zu dieser Kontroverse ]

Meine Meinung zu dieser Kontroverse:

Da ich (nur) beratend in diesem Team arbeitete fiel es sehr schwer, hier eine einigermaßen korrekte Aussage treffen zu können. Natürlich ist die erste Implementierung ein wenig Nonsens, nichtsdestotrotz befürchte ich, dass viele Leser solche Dinge heute jeden Tag bei Code Reviews sehen oder aber sogar selbst implementieren. Man weiß ja die Reihenfolge. Ist ja logisch, dass zuerst immer Username und dann Passwort kommt, oder?

Nein, meiner Meinung nach weiß man es nicht, da man es eventuell 2-5 Jahre nach der eigentlichen Implementierung bei der Pflege der Software noch wissen muss. Selbst eine noch so intelligente IDE kann hier nicht mehr helfen.

Gehen wir das andere Extrem an. Muss für jeden primitiven Datentyp in Java nun doch ein Wrapper vorhanden sein? Nein, ich empfinde das als unnötig, und meine Erfahrung bestätigt es mir (bisher 🙂 ). Der Weg des Kapselns, sobald Logik benötigt wird, welchen das Team dann einschlug, empfinde ich durchaus als sinnvoll. Die weitere Entwicklung wird dadurch strukturiert und kapselt spezielle Logik in speziellen Klassen.

Letztlich bin ich aber Fan dieser Lösung:

public String doLogin(String username, String password, String type);

Es kann eben nicht sein, dass Javadoc ignoriert wird, nur weil man es gewöhnt ist, dass dieser nicht gepflegt ist und deshalb nicht weiterhilft. Das zeigt meiner Meinung nach auf die eigentliche Ursache des Problems: Hier fehlt es an Vorgaben und Vorschriften, vermutlich auch an Metriken, die einen hier absichern, oder aber die ein schlechtes Gewissen hervorrufen. Generell wird innerhalb von Code Reviews oder beim Pair Programming viel zu wenig Wert darauf gelegt, die Dokumentation mit der realen Implementierung abzugleichen.

Ein Entwickler sollte immer die Betriebszeit der zu entwickelnden Komponente im Blick haben und die Dokumentation dementsprechend anpassen bzw. schreiben.

Wie immer innerhalb dieser Kolumne wäre ich sehr froh, wenn sich aus der Fragestellung eine interessante und spannende Diskussion ergeben würde.

Ich wusste einfach nicht mehr, in welcher Reihenfolge ich das damals implementiert habe. Wer liest schon seinen eigenen Javadoc-Kommentare!

Geschrieben von
Joachim Arrasz
Joachim Arrasz
Joachim Arrasz ist als Software- und Systemarchitekt in Karlsruhe bei der synyx GmbH & Co. KG als Leiter der CodeClinic tätig. Darüber hinaus twittert (@arrasz) und bloggt er gerne (http://blog.synyx.de/)
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.