Skip to content

Commit 399970f

Browse files
committed
docs: update visitor
1 parent 33df05a commit 399970f

File tree

2 files changed

+50
-24
lines changed

2 files changed

+50
-24
lines changed

visitor/README.md

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,38 @@ title: Visitor
33
category: Behavioral
44
language: en
55
tag:
6-
- Gang of Four
6+
- Decoupling
7+
- Extensibility
8+
- Gang of Four
9+
- Object composition
10+
- Polymorphism
711
---
812

913
## Intent
1014

11-
Represent an operation to be performed on the elements of an object structure. Visitor lets you
12-
define a new operation without changing the classes of the elements on which it operates.
15+
To represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.
1316

1417
## Explanation
1518

1619
Real-world example
1720

18-
> Consider a tree structure with army units. Commander has two sergeants under it and each sergeant
19-
> has three soldiers under them. Given that the hierarchy implements the visitor pattern, we can
20-
> easily create new objects that interact with the commander, sergeants, soldiers, or all of them.
21+
> An analogous real-world example of the Visitor design pattern can be seen in a museum tour guide system. Imagine a museum where visitors can take guided tours to learn about different types of exhibits, such as paintings, sculptures, and historical artifacts. Each exhibit type requires a different explanation, which is provided by specialized tour guides.
22+
>
23+
> In this scenario, the exhibits are like the elements in the Visitor pattern, and the tour guides are like the visitors. The museum structure remains unchanged, but new guides with new types of tours (operations) can be added without modifying the exhibits themselves. Each guide (visitor) implements a specific way to interact with the exhibits, providing detailed explanations according to their specialization, thereby separating the operations from the objects they operate on.
2124
2225
In plain words
2326

2427
> Visitor pattern defines operations that can be performed on the nodes of the data structure.
2528
2629
Wikipedia says
2730

28-
> In object-oriented programming and software engineering, the visitor design pattern is a way of
29-
> separating an algorithm from an object structure on which it operates. A practical result of this
30-
> separation is the ability to add new operations to existing object structures without modifying
31-
> the structures.
31+
> In object-oriented programming and software engineering, the visitor design pattern is a way of separating an algorithm from an object structure on which it operates. A practical result of this separation is the ability to add new operations to existing object structures without modifying the structures.
3232
3333
**Programmatic Example**
3434

35-
Given the army unit example from above, we first have the Unit and UnitVisitor base types.
35+
Consider a tree structure with army units. Commander has two sergeants under it and each sergeant has three soldiers under them. Given that the hierarchy implements the visitor pattern, we can easily create new objects that interact with the commander, sergeants, soldiers, or all of them.
36+
37+
Given the army unit example from above, we first have the `Unit` and `UnitVisitor` base types.
3638

3739
```java
3840
public abstract class Unit {
@@ -58,7 +60,7 @@ public interface UnitVisitor {
5860
}
5961
```
6062

61-
Then we have the concrete units.
63+
Then we have the concrete units `Commander`, `Sergeant`, and `Soldier`.
6264

6365
```java
6466
public class Commander extends Unit {
@@ -116,7 +118,7 @@ public class Soldier extends Unit {
116118
}
117119
```
118120

119-
Here are then some concrete visitors.
121+
Here are the concrete visitors `CommanderVisitor`, `SergeantVisitor`, and `SoldierVisitor`.
120122

121123
```java
122124
@Slf4j
@@ -201,31 +203,55 @@ Good to see you commander
201203

202204
## Class diagram
203205

204-
![alt text](./etc/visitor_1.png "Visitor")
206+
![Visitor](./etc/visitor_1.png "Visitor")
205207

206208
## Applicability
207209

208210
Use the Visitor pattern when
209211

210-
* An object structure contains many classes of objects with differing interfaces, and you want to perform operations on these objects that depend on their concrete classes.
211-
* Many distinct and unrelated operations need to be performed on objects in an object structure, and you want to avoid "polluting" their classes with these operations. Visitor lets you keep related operations together by defining them in one class. When the object structure is shared by many applications, use Visitor to put operations in just those applications that need them.
212-
* The classes defining the object structure rarely change, but you often want to define new operations over the structure. Changing the object structure classes requires redefining the interface to all visitors, which is potentially costly. If the object structure classes change often, then it's probably better to define the operations in those classes.
212+
* Use the Visitor pattern when you need to perform an operation on a group of similar kinds of objects, and you want to avoid polluting their classes with this operation.
213+
* Use it when a class structure is stable, but you need to perform new operations on the structure without changing it.
214+
* It's beneficial when the set of classes are fixed and only the operations need to be extended.
213215

214216
## Tutorials
215217

216-
* [Refactoring Guru](https://refactoring.guru/design-patterns/visitor)
217-
* [Dzone](https://dzone.com/articles/design-patterns-visitor)
218-
* [Sourcemaking](https://sourcemaking.com/design_patterns/visitor)
218+
* [Visitor - Refactoring Guru](https://refactoring.guru/design-patterns/visitor)
219+
* [Visitor Pattern Tutorial with Java Examples - DZone](https://dzone.com/articles/design-patterns-visitor)
220+
* [Visitor Design Pattern - Sourcemaking](https://sourcemaking.com/design_patterns/visitor)
219221

220222
## Known uses
221223

224+
* Compiler design, where the Visitor pattern can be used for operations like pretty printing, semantic checks, etc.
225+
* Abstract Syntax Tree (AST) processing.
226+
* Document structure processing (e.g., HTML, XML).
222227
* [Apache Wicket](https://github.com/apache/wicket) component tree, see [MarkupContainer](https://github.com/apache/wicket/blob/b60ec64d0b50a611a9549809c9ab216f0ffa3ae3/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java)
223228
* [javax.lang.model.element.AnnotationValue](http://docs.oracle.com/javase/8/docs/api/javax/lang/model/element/AnnotationValue.html) and [AnnotationValueVisitor](http://docs.oracle.com/javase/8/docs/api/javax/lang/model/element/AnnotationValueVisitor.html)
224229
* [javax.lang.model.element.Element](http://docs.oracle.com/javase/8/docs/api/javax/lang/model/element/Element.html) and [Element Visitor](http://docs.oracle.com/javase/8/docs/api/javax/lang/model/element/ElementVisitor.html)
225230
* [java.nio.file.FileVisitor](http://docs.oracle.com/javase/8/docs/api/java/nio/file/FileVisitor.html)
226231

232+
## Consequences
233+
234+
Benefits:
235+
236+
* Simplifies adding new operations: Adding a new operation is straightforward because you can add a new visitor without changing existing code.
237+
* Single Responsibility Principle: The Visitor pattern allows you to move related behavior into one class.
238+
* Open/Closed Principle: Elements can stay closed to modification while visitors are open to extension.
239+
240+
Trade-offs:
241+
242+
* Adding new element classes: If you need to add new types of elements, you'll need to change both the visitor interface and all of its concrete visitors.
243+
* Circular dependencies: In complex systems, this pattern can introduce circular dependencies between visitor and element classes.
244+
* Breaking encapsulation: Visitor pattern requires that the element classes expose enough details to allow the visitor to do its job, potentially breaking encapsulation.
245+
246+
## Related Patterns
247+
248+
* [Composite](https://java-design-patterns.com/patterns/composite/): The Visitor pattern is often used in conjunction with the Composite pattern, where the visitor can perform operations over a composite structure.
249+
* [Interpreter](https://java-design-patterns.com/patterns/interpreter/): Visitors can be used to implement the non-terminal expressions in the Interpreter pattern.
250+
* [Strategy](https://java-design-patterns.com/patterns/strategy/): Visitor can be considered a way of making strategies work on objects that they were not designed to operate on.
251+
227252
## Credits
228253

229-
* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59)
230-
* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b)
231-
* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7)
254+
* [Design Patterns: Elements of Reusable Object-Oriented Software](https://amzn.to/3w0pvKI)
255+
* [Head First Design Patterns: Building Extensible and Maintainable Object-Oriented Software](https://amzn.to/49NGldq)
256+
* [Java Design Patterns: A Hands-On Experience with Real-World Examples](https://amzn.to/3yhh525)
257+
* [Refactoring to Patterns](https://amzn.to/3VOO4F5)

visitor/src/test/java/com/iluwatar/visitor/VisitorTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ void testVisitSoldier() {
123123
}
124124
}
125125

126-
private class InMemoryAppender extends AppenderBase<ILoggingEvent> {
126+
private static class InMemoryAppender extends AppenderBase<ILoggingEvent> {
127127
private final List<ILoggingEvent> log = new LinkedList<>();
128128

129129
public InMemoryAppender() {

0 commit comments

Comments
 (0)