Wenn Sie mit Java-Programmen auf Benutzeroberflächenbasis arbeiten, können Sie bestimmten Aktionen (z. B. einem Klick auf eine Schaltfläche) Verhalten hinzufügen, indem Sie anonyme Klassen verwenden. Im folgenden Beispiel ist das GUI-Framework SWT, ich habe jedoch dieselben Probleme mit Swing- oder Android-UI-Komponenten. Nämlich die Strukturierung meiner Programme.
MenuItem sampleMenuItem = new MenuItem(popupMenu, SWT.NONE);
sampleMenuItem.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
doSomething();
// handle all table entries
for (int i=0; i<10; i++) {
doSomething2();
}
doSomething3();
doSomething4();
}
});
Natürlich könnten einige argumentieren, dass die Menge an Code im obigen Beispiel bereits die Erstellung einer dedizierten Klasse rechtfertigt, die die Logik enthält. Dies wird auch von Sonars Regel "Anonyme Klassen sollten nicht zu viele Zeilen haben" vorgeschlagen .
Interessanterweise legt diese Regel auch Folgendes fest:
squid: S1188 - Während Sie auf die Unterstützung des Abschlusses in Java warten, sind anonyme Klassen die bequemste Möglichkeit, ein Verhalten einzufügen, ohne eine dedizierte Klasse erstellen zu müssen. Diese anonymen inneren Klassen sollten jedoch nur verwendet werden, wenn das Verhalten in wenigen Zeilen ausgeführt werden kann. Bei komplexerem Code wird eine benannte Klasse benötigt.
Da die Schließungen in Java jedoch noch nicht angekommen sind, ist meine Frage, ob es elegantere Lösungen gibt als :
- Schreiben einer Reihe von Code in anonymen Klassen mit allen möglichen Nachteilen (eingeschränkte Wiederverwendung, langsameres Navigieren durch den Code, ...)
- Erstellen einer großen Anzahl dedizierter Klassen, die selbst möglicherweise nur über sehr eingeschränkte Funktionen verfügen (z. B. Überentwicklung, ...)
Um meine Frage zu erweitern: Ich möchte auch wissen, was die Best Practices in Bezug auf diesen Aspekt von Java-basierten UI-Anwendungen sind. Gibt es gut etablierte Muster?
quelle
Antworten:
Das einzige Muster, das ich gesehen habe und das funktioniert, ist "Wenn der Code zu schwer zu verstehen ist, was los ist, ist es Zeit, die Verwendung einer anonymen Klasse einzustellen."
In Ihrem Beispiel ist der Methodenkörper die anonyme Klasse. Ich könnte den "neuen SelectionAdapter" in eine eigene Zeile verschieben, um den Eröffnungs-Paren etwas offensichtlicher zu machen, aber ansonsten ist es in Ordnung. Wenn Sie in Schwierigkeiten geraten, kann eine zufällige Person nicht mehr herausfinden, wo sich der anonyme Klassen- und Methodencode befindet.
Ich habe auch eine private Variable oder Methode erstellt, um die anonyme Klasse zu halten. Ich habe so etwas aus dem Weg geräumt. Es schließt irgendwie die Lücke zwischen einer ganz neuen Klasse und hält sie in der Mitte des Codes. Einige Leute halten es zwar für einen schlechten Stil, aber meine allgemeine Faustregel lautet, zuerst die Lesbarkeit zu codieren.
quelle
Anonyme innere Klassen sind eine rein stilistische Sache; Sie existieren nicht als solche in der enthaltenden Klasse auf der Ebene der .class-Datei, die während der Kompilierung erstellt wird. Alle anonymen inneren Klassen erstellen eine separate .class-Datei, als wären sie als Klassen der obersten Ebene geschrieben worden.
Sie können dies sehen, wenn Sie zum Ausgabeverzeichnis (normalerweise mit dem Namen "out") navigieren und nach der inneren Klasse nach Namen suchen. Sie sehen eine separate Klassendatei für Ihre innere Klasse. Soweit ich mich erinnere, heißt es OuterClassName $ InnerClassName.class. Dem Konstruktor einer anonymen inneren Klasse (die erstellt wird, obwohl Sie sie nicht selbst schreiben) wird ein Verweis auf "this" übergeben, bei dem es sich natürlich um die enthaltende äußere Klasse handelt.
Begründen Sie Ihre Entscheidung also nicht mit Bedenken, "viele Klassen zu machen". Es ist eine rein stilistische Sache.
Als ich Java startete, sahen anonyme Klassen für mich wie ein großes Durcheinander aus, nur weil sie den Rhythmus der Klasse verletzten, der so etwas wie eine Methode mit variablen variablen Methoden war. Dann erschien plötzlich dieser Codestapel. Eigentlich irritieren sie mich immer noch leicht.
Ihr angeblicher Vorteil ist, dass sie das Verständnis des Codes erleichtern - Sie müssen nicht in eine andere Datei gehen, um zu sehen, was die Methode der anonymen inneren Klasse bewirkt. Aber das ist es.
Die Entscheidung ist also stilistisch und nichts weiter. Wenn es Ihnen gefällt, verwenden Sie es, wenn nicht, nicht.
Ich wollte dies nur schnell hinzufügen - Sie könnten Ihre Idee noch einmal überdenken, dass das Enthalten einer eingeschränkten Funktionalität, beispielsweise einer kurzen Methode, innerhalb einer dedizierten Klasse eine Überentwicklung darstellt. Die Klasse ist zumindest in Java die Einheit des Zusammenhalts. Überentwicklung wird nicht in Methoden pro Klasse oder sogar in der Anzahl der Klassen gemessen. OE ist zu beiden vollständig orthogonal.
quelle