Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 0.29.0
- Add conceptual visitor pattern.

## 0.28.0
- Add conceptual flyweight pattern.

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ It contains **Dart** examples for all classic **GoF** design patterns.
- [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)]
- [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)]
- [x] **Template Method** - [[Data Miner](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/template_method/data_miner)]
- [X] **Visitor** [[Shape XML Exporter](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/visitor/shapes_exporter)]
- [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)]
- [X] **Strategy** [[Reservation Cargo Spaces](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/strategy/reservation_cargo_spaces)]
- [ ] **Structural**
- [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)]
- [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)]
- [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)]
- [x] **Decorator** - [[Data Source Decoder](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/decorator/data_source_decoder)]
- [ ] **Facade**
- [x] **Flyweight** [[Conceptual](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/flyweight/conceptual)]
- [x] **Flyweight** - [[Conceptual](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/flyweight/conceptual)]
- [ ] **Proxy**

## Requirements
Expand Down
82 changes: 82 additions & 0 deletions patterns/visitor/conceptual/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Visitor pattern
Visitor is a behavioral design pattern that lets you separate algorithms from the objects on which
they operate.

Tutorial: [here](https://refactoring.guru/design-patterns/visitor).

### About example.

## Client code:
### Before:
```dart
void main() {
final list = createElements();
list.forEach(operation1);
}

Iterable<Object> createElements() {
return [
One(),
Two(),
Three(),
];
}

void operation1(Object obj) {
if (obj is One) {
print('operation1: one (param1 = ${obj.param1})');
} else if (obj is Two) {
print('operation1: two (param2 = ${obj.param2})');
} else if (obj is Three) {
print('operation1: two (param3 = ${obj.param3})');
}
}
```

### After:
```dart
void main() {
final list = createElements();

for (final e in elements) {
e.accept(visitor);
}
}

Iterable<Object> createElements() {
return [
One(),
Two(),
Three(),
];
}

class ConcreteVisitor1 implements Visitor {
@override
void visitOne(One one) {
print('operation1: one (param1 = ${one.param1})');
}

@override
void visitTwo(Two two) {
print('operation1: two (param2 = ${two.param2})');
}

@override
void visitThree(Three three) {
print('operation1: three (param3 = ${three.param3})');
}
}
```
#### Diagram:
![image](https://user-images.githubusercontent.com/8049534/174583542-5f57463c-148b-4113-acd3-2814ec017ecc.png)

### Output:
```
operation1: one (param1 = 1)
operation1: two (param2 = 2)
operation1: three (param3 = 3)
operation2: one (param1 = 1)
operation2: two (param2 = 2)
operation2: three (param3 = 3)
```
11 changes: 11 additions & 0 deletions patterns/visitor/conceptual/after/elements/one.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import '../pattern/element.dart';
import '../pattern/visitor.dart';

class One implements Element {
final String param1 = '1';

@override
void accept(Visitor visitor) {
visitor.visitOne(this);
}
}
11 changes: 11 additions & 0 deletions patterns/visitor/conceptual/after/elements/three.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import '../pattern/element.dart';
import '../pattern/visitor.dart';

class Three implements Element {
final String param3 = '3';

@override
void accept(Visitor visitor) {
visitor.visitThree(this);
}
}
11 changes: 11 additions & 0 deletions patterns/visitor/conceptual/after/elements/two.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import '../pattern/element.dart';
import '../pattern/visitor.dart';

class Two implements Element {
final String param2 = '2';

@override
void accept(Visitor visitor) {
visitor.visitTwo(this);
}
}
27 changes: 27 additions & 0 deletions patterns/visitor/conceptual/after/main.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import 'elements/one.dart';
import 'elements/three.dart';
import 'elements/two.dart';
import 'operations/concrete_visitor1.dart';
import 'operations/concrete_visitor2.dart';
import 'pattern/element.dart';
import 'pattern/visitor.dart';

void main() {
final list = createElements();
operation(list, ConcreteVisitor1());
operation(list, ConcreteVisitor2());
}

Iterable<Element> createElements() {
return [
One(),
Two(),
Three(),
];
}

void operation(Iterable<Element> elements, Visitor visitor) {
for (final e in elements) {
e.accept(visitor);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import '../elements/one.dart';
import '../elements/three.dart';
import '../elements/two.dart';
import '../pattern/visitor.dart';

class ConcreteVisitor1 implements Visitor {
@override
void visitOne(One one) {
print('operation1: one (param1 = ${one.param1})');
}

@override
void visitTwo(Two two) {
print('operation1: two (param2 = ${two.param2})');
}

@override
void visitThree(Three three) {
print('operation1: three (param3 = ${three.param3})');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import '../elements/one.dart';
import '../elements/three.dart';
import '../elements/two.dart';
import '../pattern/visitor.dart';

class ConcreteVisitor2 implements Visitor {
@override
void visitOne(One one) {
print('operation2: one (param1 = ${one.param1})');
}

@override
void visitTwo(Two two) {
print('operation2: two (param2 = ${two.param2})');
}

@override
void visitThree(Three three) {
print('operation2: three (param3 = ${three.param3})');
}
}
5 changes: 5 additions & 0 deletions patterns/visitor/conceptual/after/pattern/element.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import 'visitor.dart';

abstract class Element {
void accept(Visitor visitor);
}
11 changes: 11 additions & 0 deletions patterns/visitor/conceptual/after/pattern/visitor.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import '../elements/one.dart';
import '../elements/three.dart';
import '../elements/two.dart';

abstract class Visitor {
void visitOne(One one);

void visitTwo(Two two);

void visitThree(Three three);
}
11 changes: 11 additions & 0 deletions patterns/visitor/conceptual/before/elements/elements.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class One {
final String param1 = '1';
}

class Two {
final String param2 = '2';
}

class Three {
final String param3 = '3';
}
36 changes: 36 additions & 0 deletions patterns/visitor/conceptual/before/main.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import 'elements/elements.dart';

void main() {
final list = createElements();

list.forEach(operation1);
list.forEach(operation2);
}

Iterable<Object> createElements() {
return [
One(),
Two(),
Three(),
];
}

void operation1(Object obj) {
if (obj is One) {
print('operation1: one (param1 = ${obj.param1})');
} else if (obj is Two) {
print('operation1: two (param2 = ${obj.param2})');
} else if (obj is Three) {
print('operation1: two (param3 = ${obj.param3})');
}
}

void operation2(Object obj) {
if (obj is One) {
print('operation2: one (param1 = ${obj.param1})');
} else if (obj is Two) {
print('operation2: two (param2 = ${obj.param2})');
} else if (obj is Three) {
print('operation2: two (param3 = ${obj.param3})');
}
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: design_patterns_dart
description: Dart examples for all classic GoF design patterns.
version: 0.28.0
version: 0.29.0
homepage: https://refactoring.guru/design-patterns
repository: https://github.com/RefactoringGuru/design-patterns-dart
issue_tracker: https://github.com/RefactoringGuru/design-patterns-dart/issue
Expand Down