Best Practice in Bezug auf anonyme Klassen in UI-Anwendungen

8

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?

Jérôme
quelle
Sie würden anonyme Klassen verwenden, bei denen die Wahrscheinlichkeit einer Wiederverwendung von Code relativ gering ist und Sie mehrere Implementierungen einer Schnittstelle benötigen. Dadurch müssen Sie für jede Implementierung keine neue Klasse schreiben. Kennen Sie schon das ?
Robert Harvey
@ Robert, mir ist bewusst, dass Code, der an eine anonyme Klasse angehängt ist, normalerweise nicht zur Wiederverwendung bestimmt ist. Ich bin jedoch auf einige Fälle gestoßen, in denen ich dies trotzdem gerne hätte tun können. ZB In dem Fall, in dem ein Button und ein MenuItem denselben Code ausführen müssen, jedoch nur mit geringfügigen Anpassungen und ohne Verletzung von DRY. Aus diesem Grund suche ich nach Techniken, die eine bessere Trennung und Strukturierung meines Codes ermöglichen.
Jérôme
Sie tun dies, indem Sie die anonyme Klasse zu einer tatsächlichen Klasse hochstufen.
Robert Harvey
Wie in meiner Frage erwähnt, ist dies eine der mir bekannten Lösungen. Ich suche jedoch nach anderen Techniken oder Best Practices, falls diese existieren . Wenn es so etwas jedoch nicht gibt und wir wählen müssen, ob wir eine anonyme oder eine tatsächliche Klasse erstellen möchten, ist dies möglicherweise auch eine gültige Antwort. :-) In der Vergangenheit habe ich mit einer Reihe von GUIs in einer Reihe von gearbeitet verschiedene Programmiersprachen. Und von Delphi über Visual Studio bis hin zu Eiffel habe ich immer die Java-Methode in Betracht gezogen, bei der anonyme Klassen in Bezug auf den LOC ziemlich ausführlich verwendet wurden, um ein Ergebnis zu erzielen.
Jérôme
1
Das liegt daran, dass Java von Natur aus ausführlich ist. Sie können nicht dumm reparieren.
Robert Harvey

Antworten:

2

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.

Jim Barrows
quelle
Ich stimme Ihrem ersten Absatz voll und ganz zu. Manchmal erscheint es jedoch umständlich, eine dedizierte Klasse zu erstellen, insbesondere wenn mit der Zeit etwas wächst, das mit ein paar Zeilen beginnt. Bisher habe ich noch nie jemanden gesehen, der privaten Variablen am Ende der übergeordneten Klasse anonyme Klassen zuweist. Ich kann jedoch den Vorteil der Strukturierung des Codes erkennen, ohne viele kleine dedizierte Klassen zu erstellen. Auch wenn es ein schlechter Stil sein mag, beantwortet es teilweise meine Frage, welche anderen Techniken existieren. +1
Jérôme
1

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.

Gefallen an der Frage
quelle