Wzorzec Projektowy Odwiedzający (Visitor) w Javie
Wprowadzenie
Wzorzec projektowy Odwiedzający (Visitor) to behawioralny schemat projektowy, który pozwala na dynamiczne rozszerzanie funkcjonalności obiektów w strukturze bez ingerowania w kod tych obiektów. Jest szczególnie przydatny w sytuacjach, gdy zachodzi potrzeba dodania nowych operacji do istniejących klas, które są już zaimplementowane i przetestowane.
Kluczową koncepcją wzorca Odwiedzający są dwa interfejsy: Odwiedzający (Visitor) oraz Odwiedzany (Visitable). Interfejs Odwiedzający definiuje zestaw operacji, które mogą być wykonywane na obiektach, natomiast interfejs Odwiedzany określa sposób, w jaki obiekt „przyjmuje” odwiedzającego, przekazując mu siebie jako argument.
Implementacja wzorca Odwiedzający
Proces implementacji wzorca Odwiedzający obejmuje następujące kroki:
1. Stworzenie interfejsu Odwiedzający (Visitor)
Zdefiniuj interfejs Odwiedzający, który deklaruje metody dla każdego typu obiektu, który może być odwiedzony. Na przykład, dla kolekcji obiektów reprezentujących figury geometryczne, interfejs Odwiedzający mógłby zawierać metody takie jak odwiedźKolo
, odwiedźKwadrat
i odwiedźProstokąt
.
public interface Visitor {
void visitCircle(Circle circle);
void visitSquare(Square square);
void visitRectangle(Rectangle rectangle);
}
2. Stworzenie interfejsu Odwiedzany (Visitable)
Zdefiniuj interfejs Odwiedzany, który zawiera metodę accept
, która przyjmuje jako argument obiekt typu Odwiedzający.
public interface Visitable {
void accept(Visitor visitor);
}
3. Implementacja klas Odwiedzanych
Utwórz klasy reprezentujące elementy, które mają być odwiedzane. Klasy te powinny implementować interfejs Odwiedzany i przekazywać obiekt Odwiedzającego do odpowiedniej metody visit
.
public class Circle implements Visitable {
@Override
public void accept(Visitor visitor) {
visitor.visitCircle(this);
}
}
public class Square implements Visitable {
@Override
public void accept(Visitor visitor) {
visitor.visitSquare(this);
}
}
public class Rectangle implements Visitable {
@Override
public void accept(Visitor visitor) {
visitor.visitRectangle(this);
}
}
4. Implementacja klas Odwiedzających
Stwórz klasy implementujące interfejs Odwiedzający, które będą wykonywać konkretne operacje na obiektach. Każda z tych klas powinna implementować metody visit
dla każdego typu elementu z kolekcji.
public class DrawVisitor implements Visitor {
@Override
public void visitCircle(Circle circle) {
System.out.println("Rysowanie okręgu");
}
@Override
public void visitSquare(Square square) {
System.out.println("Rysowanie kwadratu");
}
@Override
public void visitRectangle(Rectangle rectangle) {
System.out.println("Rysowanie prostokąta");
}
}
public class AreaCalculatorVisitor implements Visitor {
private int totalArea;
@Override
public void visitCircle(Circle circle) {
totalArea += circle.getArea();
}
@Override
public void visitSquare(Square square) {
totalArea += square.getArea();
}
@Override
public void visitRectangle(Rectangle rectangle) {
totalArea += rectangle.getArea();
}
public int getTotalArea() {
return totalArea;
}
}
Użycie wzorca Odwiedzający
Aby skorzystać ze wzorca Odwiedzający, należy utworzyć obiekt Odwiedzającego i wywołać metodę accept
dla każdego elementu w kolekcji.
List<Visitable> shapes = new ArrayList<>();
shapes.add(new Circle());
shapes.add(new Square());
shapes.add(new Rectangle());
DrawVisitor drawVisitor = new DrawVisitor();
for (Visitable shape : shapes) {
shape.accept(drawVisitor);
}
AreaCalculatorVisitor areaCalculatorVisitor = new AreaCalculatorVisitor();
for (Visitable shape : shapes) {
shape.accept(areaCalculatorVisitor);
}
System.out.println("Całkowita powierzchnia: " + areaCalculatorVisitor.getTotalArea());
Zalety wzorca Odwiedzający
- Elastyczność: Umożliwia dodawanie nowych operacji na kolekcjach obiektów bez modyfikowania klas tych obiektów.
- Wielokrotne użycie: Klasy Odwiedzających mogą być wielokrotnie używane do różnych operacji na tej samej kolekcji.
- Niskie sprzężenie: Wzorzec zmniejsza zależność pomiędzy klasami elementów kolekcji i klasami wykonującymi na nich operacje.
Wady wzorca Odwiedzający
- Złożoność: Wzorzec może być skomplikowany, zwłaszcza przy dużych kolekcjach lub wielu zróżnicowanych operacjach.
- Dodatkowe obiekty: Wymaga tworzenia dodatkowych obiektów Odwiedzających, co może wpływać na wydajność.
Podsumowanie
Wzorzec Odwiedzający jest potężnym narzędziem do dynamicznego rozszerzania funkcjonalności obiektów w kolekcji. Sprawdza się szczególnie dobrze w sytuacjach, gdy trzeba dodawać nowe operacje do istniejącego systemu, który został już zaimplementowany i przetestowany.
Najczęściej Zadawane Pytania
- Czym jest wzorzec projektowy Odwiedzający?
Wzorzec Odwiedzający umożliwia rozszerzenie funkcjonalności obiektów w kolekcji bez konieczności ingerowania w kod tych obiektów.
- Jakie są korzyści ze stosowania wzorca Odwiedzający?
Zapewnia elastyczność, możliwość ponownego wykorzystania kodu i niskie sprzężenie między klasami.
- Jakie są wady wzorca Odwiedzający?
Może prowadzić do zwiększonej złożoności i wymaga tworzenia dodatkowych obiektów.
- Kiedy warto zastosować wzorzec Odwiedzający?
W sytuacji, gdy konieczne jest dodanie nowych operacji do istniejących obiektów bez modyfikacji ich struktury.
- Jak używać wzorca Odwiedzający?
Należy utworzyć obiekt Odwiedzającego i wywołać jego metodę
accept
dla każdego elementu z kolekcji. - Czym jest interfejs Odwiedzający (Visitor)?
Interfejs Odwiedzający definiuje operacje, które mogą być wykonane na elementach kolekcji.
- Czym jest interfejs Odwiedzany (Visitable)?
Interfejs Odwiedzany definiuje sposób, w jaki obiekt przyjmuje obiekt Odwiedzającego.
- Jak zaimplementować wzorzec Odwiedzający?
Należy zaimplementować interfejsy Odwiedzający i Odwiedzany, oraz utworzyć klasy, które je implementują.
- Czy wzorzec Odwiedzający jest skomplikowany?
Wzorzec może stać się skomplikowany dla rozbudowanych kolekcji lub dużej liczby operacji.
- Czy wzorzec Odwiedzający jest przydatny?
Tak, wzorzec Odwiedzający jest użyteczny, gdy trzeba dynamicznie dodawać nowe operacje do istniejącej struktury obiektów.
newsblog.pl
Maciej – redaktor, pasjonat technologii i samozwańczy pogromca błędów w systemie Windows. Zna Linuxa lepiej niż własną lodówkę, a kawa to jego główne źródło zasilania. Pisze, testuje, naprawia – i czasem nawet wyłącza i włącza ponownie. W wolnych chwilach udaje, że odpoczywa, ale i tak kończy z laptopem na kolanach.