Skip to content

Commit 45429cd

Browse files
authored
Merge pull request #67 from ilopX/add-conceptual-visitor-pattern
Add conceptual visitor pattern
2 parents 1edebd8 + 61af886 commit 45429cd

File tree

14 files changed

+253
-3
lines changed

14 files changed

+253
-3
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## 0.29.0
2+
- Add conceptual visitor pattern.
3+
14
## 0.28.0
25
- Add conceptual flyweight pattern.
36

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@ It contains **Dart** examples for all classic **GoF** design patterns.
1919
- [x] **Observer** - [[Open-Close Editor Events](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/observer/open_close_editor_events)] [[AppObserver](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/observer/app_observer)] [[![16x16](https://user-images.githubusercontent.com/8049534/171852337-57db0faf-1f5e-489a-a79a-22ed4f47b4ed.png) Subscriber Flutter Widget](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/observer/subscriber_flutter_widget)]
2020
- [x] **State** - [[Conceptual](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/state/three_state)] [[![16x16](https://user-images.githubusercontent.com/8049534/171852337-57db0faf-1f5e-489a-a79a-22ed4f47b4ed.png) State Manipulator](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/state/manipulator_state)]
2121
- [x] **Template Method** - [[Data Miner](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/template_method/data_miner)]
22-
- [X] **Visitor** [[Shape XML Exporter](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/visitor/shapes_exporter)]
22+
- [X] **Visitor** - [[Conceptual](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/visitor/conceptual)] [[Shape XML Exporter](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/visitor/shapes_exporter)]
2323
- [X] **Strategy** [[Reservation Cargo Spaces](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/strategy/reservation_cargo_spaces)]
2424
- [ ] **Structural**
2525
- [x] **Adapter** - [[Text Graphics](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/adapter/text_graphics)] [[Square Round conflict](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/adapter/square_round_conflict)] [[![16x16](https://user-images.githubusercontent.com/8049534/171852337-57db0faf-1f5e-489a-a79a-22ed4f47b4ed.png) Flutter Adapter](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/adapter/flutter_adapter)]
2626
- [x] **Bridge** - [[Remote Device Control](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/bridge/devices_remote_control)] [[Clock](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/bridge/clock)]
2727
- [x] **Composite** - [[Image Editor](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/composite/image_editor)] [[Products and Boxes](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/composite/products_and_boxes)]
2828
- [x] **Decorator** - [[Data Source Decoder](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/decorator/data_source_decoder)]
2929
- [ ] **Facade**
30-
- [x] **Flyweight** [[Conceptual](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/flyweight/conceptual)]
30+
- [x] **Flyweight** - [[Conceptual](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/flyweight/conceptual)]
3131
- [ ] **Proxy**
3232

3333
## Requirements
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# Visitor pattern
2+
Visitor is a behavioral design pattern that lets you separate algorithms from the objects on which
3+
they operate.
4+
5+
Tutorial: [here](https://refactoring.guru/design-patterns/visitor).
6+
7+
### About example.
8+
9+
## Client code:
10+
### Before:
11+
```dart
12+
void main() {
13+
final list = createElements();
14+
list.forEach(operation1);
15+
}
16+
17+
Iterable<Object> createElements() {
18+
return [
19+
One(),
20+
Two(),
21+
Three(),
22+
];
23+
}
24+
25+
void operation1(Object obj) {
26+
if (obj is One) {
27+
print('operation1: one (param1 = ${obj.param1})');
28+
} else if (obj is Two) {
29+
print('operation1: two (param2 = ${obj.param2})');
30+
} else if (obj is Three) {
31+
print('operation1: two (param3 = ${obj.param3})');
32+
}
33+
}
34+
```
35+
36+
### After:
37+
```dart
38+
void main() {
39+
final list = createElements();
40+
41+
for (final e in elements) {
42+
e.accept(visitor);
43+
}
44+
}
45+
46+
Iterable<Object> createElements() {
47+
return [
48+
One(),
49+
Two(),
50+
Three(),
51+
];
52+
}
53+
54+
class ConcreteVisitor1 implements Visitor {
55+
@override
56+
void visitOne(One one) {
57+
print('operation1: one (param1 = ${one.param1})');
58+
}
59+
60+
@override
61+
void visitTwo(Two two) {
62+
print('operation1: two (param2 = ${two.param2})');
63+
}
64+
65+
@override
66+
void visitThree(Three three) {
67+
print('operation1: three (param3 = ${three.param3})');
68+
}
69+
}
70+
```
71+
#### Diagram:
72+
![image](https://user-images.githubusercontent.com/8049534/174583542-5f57463c-148b-4113-acd3-2814ec017ecc.png)
73+
74+
### Output:
75+
```
76+
operation1: one (param1 = 1)
77+
operation1: two (param2 = 2)
78+
operation1: three (param3 = 3)
79+
operation2: one (param1 = 1)
80+
operation2: two (param2 = 2)
81+
operation2: three (param3 = 3)
82+
```
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import '../pattern/element.dart';
2+
import '../pattern/visitor.dart';
3+
4+
class One implements Element {
5+
final String param1 = '1';
6+
7+
@override
8+
void accept(Visitor visitor) {
9+
visitor.visitOne(this);
10+
}
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import '../pattern/element.dart';
2+
import '../pattern/visitor.dart';
3+
4+
class Three implements Element {
5+
final String param3 = '3';
6+
7+
@override
8+
void accept(Visitor visitor) {
9+
visitor.visitThree(this);
10+
}
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import '../pattern/element.dart';
2+
import '../pattern/visitor.dart';
3+
4+
class Two implements Element {
5+
final String param2 = '2';
6+
7+
@override
8+
void accept(Visitor visitor) {
9+
visitor.visitTwo(this);
10+
}
11+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import 'elements/one.dart';
2+
import 'elements/three.dart';
3+
import 'elements/two.dart';
4+
import 'operations/concrete_visitor1.dart';
5+
import 'operations/concrete_visitor2.dart';
6+
import 'pattern/element.dart';
7+
import 'pattern/visitor.dart';
8+
9+
void main() {
10+
final list = createElements();
11+
operation(list, ConcreteVisitor1());
12+
operation(list, ConcreteVisitor2());
13+
}
14+
15+
Iterable<Element> createElements() {
16+
return [
17+
One(),
18+
Two(),
19+
Three(),
20+
];
21+
}
22+
23+
void operation(Iterable<Element> elements, Visitor visitor) {
24+
for (final e in elements) {
25+
e.accept(visitor);
26+
}
27+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import '../elements/one.dart';
2+
import '../elements/three.dart';
3+
import '../elements/two.dart';
4+
import '../pattern/visitor.dart';
5+
6+
class ConcreteVisitor1 implements Visitor {
7+
@override
8+
void visitOne(One one) {
9+
print('operation1: one (param1 = ${one.param1})');
10+
}
11+
12+
@override
13+
void visitTwo(Two two) {
14+
print('operation1: two (param2 = ${two.param2})');
15+
}
16+
17+
@override
18+
void visitThree(Three three) {
19+
print('operation1: three (param3 = ${three.param3})');
20+
}
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import '../elements/one.dart';
2+
import '../elements/three.dart';
3+
import '../elements/two.dart';
4+
import '../pattern/visitor.dart';
5+
6+
class ConcreteVisitor2 implements Visitor {
7+
@override
8+
void visitOne(One one) {
9+
print('operation2: one (param1 = ${one.param1})');
10+
}
11+
12+
@override
13+
void visitTwo(Two two) {
14+
print('operation2: two (param2 = ${two.param2})');
15+
}
16+
17+
@override
18+
void visitThree(Three three) {
19+
print('operation2: three (param3 = ${three.param3})');
20+
}
21+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import 'visitor.dart';
2+
3+
abstract class Element {
4+
void accept(Visitor visitor);
5+
}

0 commit comments

Comments
 (0)