mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-09-13 04:18:58 +00:00
* docs: reformulate text, add links to further languages and paragraph about the book in central README.md (#2275) * docs: shorten text for link to payhip (#2275) * docs: reformulate german translation for Abstract Document (#2275) * Create folder for Abstract Factory * Create README.md for Abstract Document * Translate README.md for Abstract Document to German * correct typo * docs: add class diagrams for all patterns (#2275) * docs: add missing words in abstract-factory.README.md (#2275) * docs: Create German README.md for Active Object #2275 first text part * docs: finish German translation of README.md for Active Object * docs: translate actor-model into German #2295 * docs: add German translation for Acyclic Visitor #2295 * correct typo * docs: Translate Singleton into German #2295 * docs: Translate Prototype into German #2295 * Delete localization/de/Abstract Factory * insert line break * correct typos in actor-model * realignment of java code block * docs: translate Adapter Pattern into German #2295 * Update README.md change 'lizenz' to 'Lizenz' in badge * Update README.md translate 'benefits' and 'trade-offs' * remove additional bullet point after line break * correct indentation * docs: translate Dependency Injection into German #2295 * docs: translate Bridge into German #2295 * correct typos * docs: Translate Builder into German * delete english text * little changes in formulation * Update README.md change link to image * docs: remove spanish files (#2275) * docs: remove non-translated patterns (#2275) * Create README.md docs: Translate Step Builder into German #2275 * Create README.md docs: Translate Fluent Interface into German #2275 * eager is eifrig, not gierig * Translate Chain of Responsibility into German #2275
193 lines
6.8 KiB
Markdown
193 lines
6.8 KiB
Markdown
---
|
|
shortTitle: Acyclic Visitor
|
|
category: Behavioral
|
|
language: de
|
|
tag:
|
|
- Decoupling
|
|
- Extensibility
|
|
- Interface
|
|
- Object composition
|
|
---
|
|
|
|
## Zweck
|
|
|
|
Das Acyclic-Visitor-Pattern entkoppelt Operationen von der Objekthierarchie und erlaubt so ein flexibles Design für verschiedenste Anwendungen.
|
|
|
|
## Detailierte Erklärung
|
|
|
|
Reales Beispiel
|
|
|
|
> Als Vergleich aus der realen analogen Welt soll ein System von Museumsführern dienen.
|
|
> Stellen Sie sich ein Museum mit verschiedensten Ausstellungsstücken (Bilder, Skulpturen, historische Artefakte, ...) vor.
|
|
> Es gibt dort verschiedene Typen von Führern (Menschen, Audio-Guides, VR-Führer), die zu jedem Objekt Informationen geben.
|
|
> Wenn nun eine neue Art der Führung eingeführt wird, muss nicht jedes Ausstellungsstück dafür angepasst werden.
|
|
> Stattdessen implementiert jeder Führer eine Schnittstelle zu den jeweiligen Ausstellungstücken.
|
|
> Auf diese Weise ist das System leicht erweiterbar.
|
|
|
|
In einfachen Worten
|
|
|
|
> Acyclic Visitor erlaubt das Hinzufügen von Funktionen, ohne die bestehende Hierarchie anpassen zu müssen.
|
|
|
|
[WikiWikiWeb](https://wiki.c2.com/?AcyclicVisitor) sagt:
|
|
|
|
> Das Acyclic-Visitor-Pattern erlaubt es, neue Funktionen zu einer bestehenden Klassenhierarchie
|
|
> hinzuzufügen, ohne diese Hierarchie zu verändern und ohne Abhängigkeitszyklen (wie beim Visitor Pattern) zu schaffen.
|
|
|
|
Ablaufdiagramm
|
|
|
|

|
|
|
|
|
|
## Programmbeispiel
|
|
|
|
Wir betrachten eine Hierarchie von Modem-Klassen. Die Modems werden besucht von einem externen Algorithmus,
|
|
der auf Filterkritien (Unix- oder DOS-Kompatibilität) basiert.
|
|
|
|
Here die `Modem` Hierarchie.
|
|
|
|
```java
|
|
public abstract class Modem {
|
|
public abstract void accept(ModemVisitor modemVisitor);
|
|
}
|
|
|
|
public class Zoom extends Modem {
|
|
|
|
// Weitere Eigenschaften und Methoden ...
|
|
|
|
@Override
|
|
public void accept(ModemVisitor modemVisitor) {
|
|
if (modemVisitor instanceof ZoomVisitor) {
|
|
((ZoomVisitor) modemVisitor).visit(this);
|
|
} else {
|
|
LOGGER.info("Only ZoomVisitor is allowed to visit Zoom modem");
|
|
}
|
|
}
|
|
}
|
|
|
|
public class Hayes extends Modem {
|
|
|
|
// Weitere Eigenschaften und Methoden...
|
|
|
|
@Override
|
|
public void accept(ModemVisitor modemVisitor) {
|
|
if (modemVisitor instanceof HayesVisitor) {
|
|
((HayesVisitor) modemVisitor).visit(this);
|
|
} else {
|
|
LOGGER.info("Only HayesVisitor is allowed to visit Hayes modem");
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
Danach führen wir die `ModemVisitor` Hierarchie ein.
|
|
|
|
```java
|
|
public interface ModemVisitor {
|
|
}
|
|
|
|
public interface HayesVisitor extends ModemVisitor {
|
|
void visit(Hayes hayes);
|
|
}
|
|
|
|
public interface ZoomVisitor extends ModemVisitor {
|
|
void visit(Zoom zoom);
|
|
}
|
|
|
|
public interface AllModemVisitor extends ZoomVisitor, HayesVisitor {
|
|
}
|
|
|
|
public class ConfigureForDosVisitor implements AllModemVisitor {
|
|
|
|
// Weitere Eigenschaften und Methoden...
|
|
|
|
@Override
|
|
public void visit(Hayes hayes) {
|
|
LOGGER.info(hayes + " used with Dos configurator.");
|
|
}
|
|
|
|
@Override
|
|
public void visit(Zoom zoom) {
|
|
LOGGER.info(zoom + " used with Dos configurator.");
|
|
}
|
|
}
|
|
|
|
public class ConfigureForUnixVisitor implements ZoomVisitor {
|
|
|
|
// Weitere Eigenschaften und Methoden...
|
|
|
|
@Override
|
|
public void visit(Zoom zoom) {
|
|
LOGGER.info(zoom + " used with Unix configurator.");
|
|
}
|
|
}
|
|
```
|
|
|
|
Schließlich die Visitors im Einsatz.
|
|
|
|
```java
|
|
public static void main(String[] args) {
|
|
var conUnix = new ConfigureForUnixVisitor();
|
|
var conDos = new ConfigureForDosVisitor();
|
|
|
|
var zoom = new Zoom();
|
|
var hayes = new Hayes();
|
|
|
|
hayes.accept(conDos); // Hayes modem with Dos configurator
|
|
zoom.accept(conDos); // Zoom modem with Dos configurator
|
|
hayes.accept(conUnix); // Hayes modem with Unix configurator
|
|
zoom.accept(conUnix); // Zoom modem with Unix configurator
|
|
}
|
|
```
|
|
|
|
Programausgabe:
|
|
|
|
```
|
|
09:15:11.125 [main] INFO com.iluwatar.acyclicvisitor.ConfigureForDosVisitor -- Hayes modem used with Dos configurator.
|
|
09:15:11.127 [main] INFO com.iluwatar.acyclicvisitor.ConfigureForDosVisitor -- Zoom modem used with Dos configurator.
|
|
09:15:11.127 [main] INFO com.iluwatar.acyclicvisitor.Hayes -- Only HayesVisitor is allowed to visit Hayes modem
|
|
09:15:11.127 [main] INFO com.iluwatar.acyclicvisitor.ConfigureForUnixVisitor -- Zoom modem used with Unix configurator.
|
|
```
|
|
|
|
## Verwendung
|
|
|
|
* Wenn Sie zu einer bestehenden Hierarchie eine neue Funktion hinzufügen müssen, ohne die Hierarchie zu verändern.
|
|
* Wenn es Funktionen gibt, die zwar auf einer Hierarchie arbeiten, aber nicht selbst dazu gehören (Wie die Configure-Funktionen im obigen Beispiel).
|
|
* Wenn abhängig vom Objekttyp sehr unterschiedliche Funktionen auszuführen sind.
|
|
* Wenn die zu besuchende Klassenhierarchie häufig um neue Kindklassen erweitert wird.
|
|
* When the visited class hierarchy will be frequently extended with new derivatives of the Element class.
|
|
* Wenn es sehr aufwendig ist, die neuen Kindklassen zu kompilieren, zu verlinken, zu testen oder zu verteilen.
|
|
|
|
## Tutorials
|
|
|
|
* [The Acyclic Visitor Pattern (Code Crafter)](https://codecrafter.blogspot.com/2012/12/the-acyclic-visitor-pattern.html)
|
|
|
|
## Vor- und Nachteile
|
|
|
|
Vorteile:
|
|
|
|
* Erweiterbarkeit: Neue Funktionen können leicht hinzugefügt werden, ohne die Objektstruktur zu verändern.
|
|
* Entkopplung: Kopplung zwischen Objekten und den auf ihnen stattfindenden Operationen wird reduziert.
|
|
* Keine Abhängigkeitszyklen: Abhängigkeiten sind azyklisch, Wartbarkeit verbessert sich, Komplexität wird reduziert.
|
|
|
|
Nachteile:
|
|
|
|
* Komplexität: Viele erforderliche Visitor-Interfaces können die Komplexität erhöhen.
|
|
* Wartbarkeit: Änderungen an der Objekthierarchie erfordern Updates aller Visitoren.
|
|
|
|
## Verwandte Patterns
|
|
|
|
* [Composite](https://java-design-patterns.com/patterns/composite/):
|
|
Wird oft zusammen mit Acyclic Visitor verwendet, um einzelne Objekte und Zusammensetzungen aus ihnen einheitlich zu behandeln.
|
|
* [Decorator](https://java-design-patterns.com/patterns/decorator/):
|
|
Can als Ergänzung eingesetzt werden, um Objekten Verantwortlichkeiten dynamisch zuzuweisen.
|
|
* [Visitor](https://java-design-patterns.com/patterns/visitor/): Acyclic Visitor ist eine Variante des Visitor Patterns, die zyklische Abhängigkeiten vermeidet.
|
|
|
|
## Quellen
|
|
|
|
* [Design Patterns: Elements of Reusable Object-Oriented Software](https://amzn.to/3w0pvKI)
|
|
* [Head First Design Patterns: Building Extensible and Maintainable Object-Oriented Software](https://amzn.to/49NGldq)
|
|
* [Java Design Patterns: A Hands-On Experience with Real-World Examples](https://amzn.to/3yhh525)
|
|
* [Patterns in Java: A Catalog of Reusable Design Patterns Illustrated with UML](https://amzn.to/4bOtzwF)
|
|
* [Acyclic Visitor (Robert C. Martin)](http://condor.depaul.edu/dmumaugh/OOT/Design-Principles/acv.pdf)
|
|
* [Acyclic Visitor (WikiWikiWeb)](https://wiki.c2.com/?AcyclicVisitor)
|