Im Zusammenhang mit diesem Thread bin ich über einen Link gestolpert. (Ich dachte, das wäre von hier aus verlinkt worden, aber vermutlich war es doch von Stackoverflow - hatte mal allgemeiner nach dem Thema gesucht). Dieser Link war OOP Alternative to Utility Classes - Yegor Bugayenko . Wirklich überzeugt hatte mich das nicht. Eher erinnerte mich das an einen Fall, wo aus der Aussage „Wenn man nur einen Hammer hat, sieht jedes Problem wie ein Nagel aus“ geschlossen wurde, dass man einen Nagel lieber mit einem Schraubenschlüssel einhämmern sollte, um nicht Gefahr zu laufen, sich dem Vorwurf dieser Aussage ausgesetzt zu sehen.
Wie auch immer, aus Neugier hatte ich dann mal weitergesucht, was der Autor sonst noch so macht. Unter anderem dieses Projekt: GitHub - yegor256/takes: True Object-Oriented Java Web Framework without NULLs, Static Methods, Annotations, and Mutable Objects Wo in der readme steht:
- not a single null (why NULL is bad?)
- not a single public static method (why they are bad?)
- not a single mutable class (why they are bad?)
- not a single instanceof keyword, type casting, or reflection (why?)
(mit jeweils verlinkten Blog-Einträgen mit den Erklärungen).
[ot]
Man könnte für jeden der Punkte einen eigenen Thread aufmachen, aber kurz:
-
Man sollte abwägen. Zu versuchen, grundsätzlich auf null zu verzichten, ist IMHO albern. Dazu ist es ZU sehr Teil der Sprache (schon bei „map.get(unknownKey)“ u.v.a.). Da auf Biegen und Brechen Optionals drumzuwickeln macht auch keinen Sinn, aber um zu sehen, wie er sie ansonsten vermeidet, müßte ich aber den Code noch genauer lesen.
-
Dazu gleich 
-
Ja, minimize Mutability, schon OK, aber die Fälle, wo das absolut möglich ist, sind IMHO Ausnahmen
-
Klar
[/ot]
Zum eigentlichen Punkt:
- not a single public static method (why they are bad?)
Da steckt etwas drin, worauf ich ja mehrfach rumgehackt hatte: public !!!. Er verwendet „private static“ auch recht oft. Ist auch gut so, IMHO. (Und, wenn ich das richtig verstanden habe, ist damit der kontroverseste Punkt dieses Threads ja auch abgefrühstückt).
[ot]
(Eigentlich noch „on topic“, aber …)
Ich finde, dass auch „public static“ Methods OK sein können. In einer meiner libraries sind z.B. viele („alle“) Funktionen „public static“: DoubleTuples. Das war eine bewußte Entscheidung: Die Funktionen sind dort „kanonisch“ implementiert. Ich weiß, das ist nicht OO, es macht in mancher Hinsicht (!) keinen Sinn, und es gibt vieles, was dafür spricht, diese Methoden als Instanzmethoden in das DoubleTuple interface zu ziehen, und die kanonischen Implementierungen in die Abtrakte Basisklasse zu packen. Aber das habe ich nicht gemacht, weil ich die Funktionen, wie auch mehrfach erwähnt, als „building blocks“ ansehe, und die Option, die ich eher in Betracht ziehe, die ist, diese Methoden für die Implementierung der Instanzmethoden mit „default“-Implementierungen direkt im Interface anzubieten
interface MutableDoubleTuple ... {
default void add(DoubleTuple other) {
DoubleTuples.add(this, other, this);
}
}
[ot]
Offtopiception:
Und wem jetzt die Frage auf der Zunge liegt, welche Methoden es mit welchen Semantiken geben sollte…
a.add(b); // a += b
a.add(b, c); // a = b + c ?
c = a.add(b); // c = a + b
...
der wird vielleicht zu ähnlichen Selbstzweifeln und schlaflosen Nächten gelangen, wie ich, und am Ende zu der Einsicht, dass die Funktionalität, zwei (immutable) Tuples zu addieren und das Ergebnis in ein drittes (mutables) zu schreiben kanonisch, universell, „minimal“ und all diesen Funktionen gemein ist - und damit ja … irgendwie ausgelagert werden könnte… oder sollte… …)
[/ot]
[/ot]
Was mich dann aber an der Readme dieses so auf „Schönheit“, „Best Practices“ und „Prinzipien“ pochenden Projektes irritiert hat, waren die Codesnippets:
public final class App {
public static void main(final String... args) throws Exception {
new FtBasic(
new TkFork(new FkRegex("/", "hello, world!")), 8080
).start(Exit.NEVER);
}
}
:eek: new
, new
, new
überall!
Eine „Best practice“ sehe ich persönlich darin: Keine public classes mit public constructors!. Zumindest wird man in o.g. „ND“-library keine öffentliche Klasse mit öffentlichem Konstruktor finden, die direkt mit „new“ instantiiert wird. Ich will das nicht mit Item 1 aus Effective Java begründen:
Consider static factory methods instead of constructors
(Ja, „consider“ heißt „consider“, und nicht „always use“). Aber ich finde das Muster von
interface MyModel { ... }
/*not public*/ class DefaultMyModel implements MyModel { ... }
public class MyModels { public static MyModel create() { ... } }
so klar, einfach, sauber und „etabliert“, dass es selten Gründe gibt, davon abzuweichen.
Nach einer kurzen Suche (z.B. bei Guice) sieht es so aus, als wäre sowas ja nur mit einigen Krämfen und Workarounds zu Injecten -_- Aber nochmal genauer schauen…