Warum ist extends JFrame implements ActionListener
eine schlechte Designentscheidung?JFrame-Unterklasse und ActionListener-Schnittstellenimplementierung
Antwort
Ein paar Punkte:
- ein
JFrame
ist wahrscheinlich eine falsche Ansatz Erweiterung - eine
ActionListener
auf einemJFrame
Die Implementierung wird wahrscheinlich zu nicht-OOP Code führen.
Falscher Ansatz?
Wenn die Idee ist, dass eine GUI-Anwendung gemacht wird, dann macht man nicht eine Erweiterung von JFrame
, sondern schreibt tatsächlich eine Anwendung.
Daher wäre die JFrame
Teil einer Anwendung, nicht die Anwendung selbst. Daher sollte JFrame
ein Objekt in der Klasse sein.
eine ActionListener
auf einem JFrame
Implementierung wahrscheinlich
Betrachten Sie den folgenden Fall zu nicht-OOP Code führen - wie die GUI-Anwendung beginnt, groß zu bekommen, und wir beginnen, eine Menge Tasten hinzufügen und Menüs, die ActionEvent
s ergeben.
Wenn die JFrame
selbst die Ereignisse erhalten würde, wie würde dann die Methode actionPerformed
aussehen?
Wahrscheinlich so etwas wie dieses:
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
// Find out which component fired the event
if (source == masterButton) {
// ... do something
} else if (source == anotherButton) {
// ... do something else
} else if (...)
// ... and so on ...
} else if (...)
// ... and so on ...
}
}
Huch.
Wir werden anfangen, Code zu bekommen, der eng an alle Komponenten in der Anwendung gekoppelt ist, und die Wartbarkeit wird in kürzester Zeit aus dem Fenster sein.
Wenn zum Beispiel die GUI Anwendungsinstanzen von ActionLister
s hatte, die auf jede Komponente reagiert, dann würden wir in der Lage sein, die Aktionen und die Kopplung des actionPerformed
Verfahren mit allen Komponenten in der aufzubrechen GUI.
Zum Beispiel:
JButton masterButton = new JButton();
masterButton.addActionListener(new MasterButtonActionListener());
JButton anotherButton = new JButton();
anotherButton.addActionListener(new AnotherButtonActionListener());
Auf diese Weise wird es ActionListeners
für jede Taste sein, die vermutlich unterschiedliche Funktionen haben. Die Verantwortung des MasterButtonActionListener
wäre, Ereignisse von der masterButton
zu behandeln - es muss nicht über andere Knöpfe in der Anwendung wissen.
Dies würde auch die Wiederverwendbarkeit der Komponenten in anderen Anwendungen oder anderen Teilen der Anwendung fördern, ohne Teile der monolithischen if-else
-Anweisung in der actionPerformed
-Methode kopieren und einfügen zu müssen.
Wenn Sie Effective Java lesen, Artikel 16 heißt es:
"Favor Zusammensetzung über inheritence"
. Lesen Sie die Erklärung gegeben here
Hallo Amir, könnten Sie vielleicht sagen, das ist ein einfacher Weg? Ich bin sehr verrostet mit meiner JAVA-Syntax - also erbt man von der anderen - aber das ist eine schlechte Idee, weil man eine "normale konkrete Klasse" ist. – JHarley1
Hi JHarley - was er dort sagt über nicht erbt von einer normalen konkreten Klasse von einem anderen Paket ist einfach, dass Änderungen in dieser Klasse direkt auf Ihre auswirken. Wenn Sie einen Verweis auf einen JFrame beibehalten, können Sie dessen Verhalten einkapseln - mit Unterschichten können Sie das nicht. –
Ich glaube, dass es ein schlechtes Design .. Weil Sie Controller-Code mit Blick mischen .. Wenn Sie MVC-Muster folgen wollen, sollten Sie sie nicht mischen ..
Zusätzlich A JFrame
erhält im Allgemeinen keine Aktionen. Seine Kindobjekte wären die Wohltäter einer ActionEvent
.
Ein besserer und mehr OO-Ansatz wäre, getrennte Aktionsobjekte zu haben. Auf diese Weise können Sie Funktionalität und Status von einer Komponente trennen. Dadurch wird Ihr Code wiederverwendbar, da Sie beispielsweise die gleiche Aktion für eine Schaltfläche und einen Menüeintrag verwenden können.
Beispiel:
class ExitAction extends AbstractAction{
public ExitAction(){
super("Exit");
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Exiting");
}
}
JButton exitButton = new JButton(new ExitAction());
Werfen Sie einen Blick auf How to Use Actions in den Java-Tutorial:
- 1. SQL Server UND UND ODER UND UND
- 2. Unterschied zwischen - und - oder 'und' oder "und"
- 3. SubSonic "Oder" und "UND"
- 4. "und" und Tail-Rekursion
- 5. SOX und Ein- und Ausblenden
- 6. QOpenGLWidget und glReadPixels und Tiefenpuffer
- 7. Flasche und Skalierung und Gleichzeitigkeit
- 8. Realm: kombinieren "oder" und "und"
- 9. ArrayList und String [] UND Objekt []
- 10. Python wenn Bedingung und "und"
- 11. Schienen und Markdown und Editor
- 12. Jack und Jill und destinationDir
- 13. Excel Multiple IF und UND
- 14. Spring und JSF und JPA
- 15. Kopf- und Fußzeile und Freemarker
- 16. Android und onSaveInstance und Restore
- 17. Hibernate und Transaktionen und Tabellensperren
- 18. „Und“ und „Oder“ auf NSPredicates
- 19. reagieren und setState und Autocomplete
- 20. Codierung und Decodierung mit PHP und JavaScript und Datenattribute Validierungs
- 21. Leistung und Sortierung und eindeutige eindeutige zwischen mysql und php
- 22. Batch-Datei umbenennen und verschieben und Variablen und Dinge
- 23. Mit 'und' und 'oder' Logik mit Dropdown-Menüs und MixItUp
- 24. bash: Umleitung (und hängen) stdout und stderr Datei und Terminal und die richtige Exit-Status
- 25. Warum scheinen NSString und NSLog% C und% lc (und% S und% ls) unterschiedlich zu behandeln?
- 26. Breite und Länge, x und y und Unterschiede beim Plotten: geosphere und ggmap
- 27. User Controls und JavaScript und Masterseiten
- 28. HTTP GET und POST Semantik und Einschränkungen
- 29. WMODE und Flash Video - Stabilität und Leistung
- 30. Gunicorn und Django mit Upstart und Nginx
Ist das eine Hausaufgabe? –
@Dave Jarvis: Nein, es ist eine sprachspezifische Frage für eine Sprache, die ich nicht verstehe. – JHarley1