Das oben beschriebene Szenario ist eine klare Verletzung des SRP (Wikipedia tut so, als ob es nur auf Klassen anwendbar wäre, dabei ist es sowohl auf höherer Ebene - wie Packages, Module, Bibliotheken - als auch auf niedriger Ebene - wie Methoden - nützlich).
Es gibt in deinem Beispiel zwei Gründe, warum sich deine printUsage
-Methode ändern könnte: Wenn sich das Ausgabeformat ändern, oder der Ort, an den es geschrieben wird. Letzteres ist gar nicht einmal so unwahrscheinlich (man denke an eine Log-Datei oder Swing-Console). Was ist, wenn du ein zusätzliches Ausgabeformat unterstützen willst (etwa ausführlicher zur Debug-Unterstützung)? Was ist, wenn du woandershin schreiben willst? Was ist, wenn du dieselbe Ausgabe sowohl auf der Konsole wie auch in der Log-Datei haben willst? Das heißt, deine Methode ist unflexibel und zu stark auf den aktuellen Fall spezialisiert.
Eine offensichtliche Verbesserung wäre, den Stream für die Ausgabe nicht hart festzuschreiben:
public static void printUsage(OutputStream os){
PARSER.printUsage(os);
}
Die Methode wird nun nicht nur flexibler, sondern ist automatisch auch testbar - einfach einen ByteArrayOutputStream mitgeben und auslesen. Wenn der Aufruf zu unbequem ist, kann man immer noch eine nicht zu testende (weil triviale) Bequemlichkeitsmethode schreiben:
public static void printUsage(){
printUsage(System.out);
}
Hier wahrscheinlich weniger sinnvoll (aber dazu müsste man die Struktur besser kennen), aber bei anderen Seiteneffekt-Methoden eventuell hilfreich ist, die eigentliche Berechnung von der Anwendung des Seiteneffekts zu trennen. Dann kann man die eventuell komplizierte Berechnung problemlos testen, und der Seiteneffekt ist dann oft so trivial, dass man sich einen Test schenken kann, oder nur eine grobe Prüfung wie “ja, es ist etwas passiert, und es ist dabei kein Fehler aufgetreten” notwendig ist:
public static String getUsage() {
return PARSER.getUsage();
}
public static void printUsage(String output){
System.out.println(output);
}