Skip to content

Commit 0318c46

Browse files
authored
Merge pull request #64 from ilopX/add-template-method-pattern
Add template method pattern
2 parents 6397334 + 7cfd7c5 commit 0318c46

File tree

15 files changed

+388
-3
lines changed

15 files changed

+388
-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.27.0
2+
- Add template method pattern: Data Miner.
3+
14
## 0.26.0
25
- Add conceptual mediator pattern.
36

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ It contains **Dart** examples for all classic **GoF** design patterns.
1414
- [x] **Command** - [[Text Editor](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/command/text_editor)]
1515
- [ ] Interpreter
1616
- [ ] **Iterator**
17-
- [x] **Mediator** [[Conceptual](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/mediator/conceptual)]
17+
- [x] **Mediator** - [[Conceptual](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/mediator/conceptual)]
1818
- [x] **Memento** - [[Conceptual](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/memento/conceptual)] [[![16x16](https://user-images.githubusercontent.com/8049534/171852337-57db0faf-1f5e-489a-a79a-22ed4f47b4ed.png) Memento Editor](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/memento/memento_editor)]
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)]
21-
- [ ] **Template Method**
21+
- [x] **Template Method** - [Data Miner](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/template_method/data_miner)
2222
- [X] **Visitor** [[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**
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Template Method Pattern
2+
Template Method is a behavioral design pattern that defines the skeleton of an algorithm in the
3+
superclass but lets subclasses override specific steps of the algorithm without changing its
4+
structure.
5+
6+
Tutorial: [here](https://refactoring.guru/design-patterns/template-method).
7+
8+
## Diagram:
9+
![image](https://user-images.githubusercontent.com/8049534/174060908-402eea9b-a030-4e45-8e95-54cfcac61bb6.png)
10+
11+
### Client code:
12+
```dart
13+
void main() {
14+
print('HTMLMiner');
15+
HTMLMiner('google_workers.html').mine();
16+
17+
print('CsvMiner');
18+
CsvMiner('twitter_workers.csv').mine();
19+
20+
print('GuruMiner');
21+
GuruMiner('refactoring_guru_workers.guru').mine();
22+
}
23+
```
24+
25+
### Output:
26+
```
27+
HTMLMiner
28+
Name Index
29+
-------------------------------
30+
Ayana White 33.92
31+
Dillan Ewing 6.21
32+
Kimora Arroyo 84.7
33+
Aspen Simmons 93.08
34+
Giana Perry 67.56
35+
Luz Carson 69.88
36+
Kaleb Pineda 47.87
37+
Kianna Bautista 3.09
38+
Jorge Reeves 16.52
39+
Leroy Morrow 51.24
40+
Ashlyn Crawford 7.25
41+
Yasmine Hampton 38.42
42+
-------------------------------
43+
sum: 519.74
44+
len: 12
45+
46+
CsvMiner
47+
Name Index
48+
-------------------------------
49+
Laylah Whitehead 22.1
50+
Karissa Arellano 2.0
51+
Maggie Mcmahon 12.25
52+
Ariel Bartlett 8.1
53+
Rashad Herman 5.8
54+
Rachael Hickman 5.22
55+
Tara Spence 9.48
56+
Kiera Cervantes 4.0
57+
Shane Robertson 9.0
58+
Perla Yoder 67.3
59+
-------------------------------
60+
sum: 145.25
61+
len: 10
62+
63+
ZipMiner
64+
Name Index
65+
-------------------------------
66+
Dmitry Zhart 62.4
67+
Alexander Shvets 44.6
68+
Fishchenko Ilya 1.4
69+
-------------------------------
70+
sum: 108.4
71+
len: 3
72+
```
73+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import 'miners/csv_miner.dart';
2+
import 'miners/zip_miner.dart';
3+
import 'miners/html_analyzer.dart';
4+
5+
void main() {
6+
print('HTMLMiner');
7+
HTMLMiner('google_workers.html').mine();
8+
9+
print('CsvMiner');
10+
CsvMiner('twitter_workers.csv').mine();
11+
12+
print('GuruMiner');
13+
ZipMiner('refactoring_guru_workers.zip').mine();
14+
}
15+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import '../pattern/data_miner.dart';
2+
import '../utils/raw_data.dart';
3+
4+
class CsvMiner extends DataMiner {
5+
CsvMiner(super.fileName);
6+
7+
@override
8+
StringTable parseData(RawData raw) {
9+
return raw.split('\n').map((line) => line.split(',')).toList();
10+
}
11+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import '../pattern/data_miner.dart';
2+
import '../utils/raw_data.dart';
3+
4+
class HTMLMiner extends DataMiner {
5+
HTMLMiner(super.fileName);
6+
7+
@override
8+
StringTable parseData(RawData raw) {
9+
String regexString = r'<td class="s0"[^>]+>(.+)<\/td>'
10+
r'\s+'
11+
r'<td class="s1"[^>]+>(.+)<\/td>';
12+
final regExp = RegExp(regexString);
13+
final matches = regExp.allMatches(raw);
14+
15+
return [
16+
for (final employer in matches)
17+
[
18+
employer.group(1)!,
19+
employer.group(2)!,
20+
]
21+
];
22+
}
23+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import 'dart:io';
2+
3+
import '../pattern/data_miner.dart';
4+
import '../utils/raw_data.dart';
5+
6+
class ZipMiner extends DataMiner {
7+
ZipMiner(super.fileName);
8+
9+
@override
10+
RawData extractData(File file) {
11+
final content = File('${reportPath}refactoring_guru_workers.zip')
12+
.readAsBytesSync()
13+
.toList();
14+
final unzip = GZipCodec().decode(content);
15+
return String.fromCharCodes(unzip);
16+
}
17+
18+
@override
19+
StringTable parseData(RawData raw) {
20+
final lines = raw.split('\n');
21+
final divIndex = lines.length ~/ 2;
22+
final names = lines.sublist(0, divIndex);
23+
final indexes = lines.sublist(divIndex);
24+
25+
return [
26+
for (var i = 0; i < divIndex; i++)
27+
[
28+
names[i].trim(),
29+
indexes[i].trim(),
30+
]
31+
];
32+
}
33+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import 'dart:io';
2+
3+
import '../utils/analysis.dart';
4+
import '../utils/formatted_table.dart';
5+
import '../utils/raw_data.dart';
6+
7+
abstract class DataMiner {
8+
final String fileName;
9+
10+
DataMiner(this.fileName);
11+
12+
void mine() {
13+
final file = openFile();
14+
final raw = extractData(file);
15+
final table = parseData(raw);
16+
final analysis = analyzeData(table);
17+
sendReport(analysis, table);
18+
}
19+
20+
File openFile() {
21+
final file = File(reportPath + fileName);
22+
23+
if (!file.existsSync()) {
24+
throw 'File not exists.';
25+
}
26+
27+
return file;
28+
}
29+
30+
RawData extractData(File file) {
31+
return file.readAsStringSync();
32+
}
33+
34+
StringTable parseData(RawData raw);
35+
36+
Analysis analyzeData(StringTable table) {
37+
return Analysis(table);
38+
}
39+
40+
void sendReport(Analysis analysis, StringTable table) {
41+
final formattedTable = FormattedTable();
42+
43+
formattedTable
44+
..addRow('Name', 'Index')
45+
..addLine();
46+
47+
for (final row in table) {
48+
final name = row[0];
49+
final index = double.parse(row[1]);
50+
51+
formattedTable.addRow(name, index);
52+
}
53+
54+
formattedTable
55+
..addLine()
56+
..addRow('sum:', analysis.sum)
57+
..addRow('len:', analysis.len);
58+
59+
print(formattedTable.toString());
60+
}
61+
62+
String get reportPath => '${Platform.script.pathSegments.sublist(
63+
0,
64+
Platform.script.pathSegments.length - 1,
65+
).join(
66+
Platform.pathSeparator,
67+
)}'
68+
'${Platform.pathSeparator}'
69+
'reports'
70+
'${Platform.pathSeparator}';
71+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
2+
<link type="text/css" rel="stylesheet" href="resources/sheet.css">
3+
<style type="text/css">
4+
.ritz .waffle a { color: inherit; }.ritz .waffle .s1{background-color:#ffffff;text-align:right;color:#000000;font-family:'Arial';font-size:10pt;vertical-align:bottom;white-space:nowrap;direction:ltr;padding:2px 3px 2px 3px;}.ritz .waffle .s0{background-color:#ffffff;text-align:left;color:#000000;font-family:'docs-Roboto',Arial;font-size:10pt;vertical-align:bottom;white-space:nowrap;direction:ltr;padding:2px 3px 2px 3px;}
5+
</style>
6+
<div class="ritz grid-container" dir="ltr">
7+
<table class="waffle" cellspacing="0" cellpadding="0">
8+
<thead>
9+
<tr>
10+
<th class="row-header freezebar-origin-ltr"></th>
11+
<th id="0C0" style="width:131px;" class="column-headers-background">A</th>
12+
<th id="0C1" style="width:100px;" class="column-headers-background">B</th>
13+
</tr>
14+
</thead>
15+
<tbody>
16+
<tr style="height: 20px">
17+
<th id="0R0" style="height: 20px;" class="row-headers-background">
18+
<div class="row-header-wrapper" style="line-height: 20px">1</div>
19+
</th>
20+
<td class="s0" dir="ltr">Ayana White</td>
21+
<td class="s1" dir="ltr">33.92</td>
22+
</tr>
23+
<tr style="height: 20px">
24+
<th id="0R1" style="height: 20px;" class="row-headers-background">
25+
<div class="row-header-wrapper" style="line-height: 20px">2</div>
26+
</th>
27+
<td class="s0" dir="ltr">Dillan Ewing</td>
28+
<td class="s1" dir="ltr">6.21</td>
29+
</tr>
30+
<tr style="height: 20px">
31+
<th id="0R2" style="height: 20px;" class="row-headers-background">
32+
<div class="row-header-wrapper" style="line-height: 20px">3</div>
33+
</th>
34+
<td class="s0" dir="ltr">Kimora Arroyo</td>
35+
<td class="s1" dir="ltr">84.7</td>
36+
</tr>
37+
<tr style="height: 20px">
38+
<th id="0R3" style="height: 20px;" class="row-headers-background">
39+
<div class="row-header-wrapper" style="line-height: 20px">4</div>
40+
</th>
41+
<td class="s0" dir="ltr">Aspen Simmons</td>
42+
<td class="s1" dir="ltr">93.08</td>
43+
</tr>
44+
<tr style="height: 20px">
45+
<th id="0R4" style="height: 20px;" class="row-headers-background">
46+
<div class="row-header-wrapper" style="line-height: 20px">5</div>
47+
</th>
48+
<td class="s0" dir="ltr">Giana Perry</td>
49+
<td class="s1" dir="ltr">67.56</td>
50+
</tr>
51+
<tr style="height: 20px">
52+
<th id="0R5" style="height: 20px;" class="row-headers-background">
53+
<div class="row-header-wrapper" style="line-height: 20px">6</div>
54+
</th>
55+
<td class="s0" dir="ltr">Luz Carson</td>
56+
<td class="s1" dir="ltr">69.88</td>
57+
</tr>
58+
<tr style="height: 20px">
59+
<th id="0R6" style="height: 20px;" class="row-headers-background">
60+
<div class="row-header-wrapper" style="line-height: 20px">7</div>
61+
</th>
62+
<td class="s0" dir="ltr">Kaleb Pineda</td>
63+
<td class="s1" dir="ltr">47.87</td>
64+
</tr>
65+
<tr style="height: 20px">
66+
<th id="0R7" style="height: 20px;" class="row-headers-background">
67+
<div class="row-header-wrapper" style="line-height: 20px">8</div>
68+
</th>
69+
<td class="s0" dir="ltr">Kianna Bautista</td>
70+
<td class="s1" dir="ltr">3.09</td>
71+
</tr>
72+
<tr style="height: 20px">
73+
<th id="0R8" style="height: 20px;" class="row-headers-background">
74+
<div class="row-header-wrapper" style="line-height: 20px">9</div>
75+
</th>
76+
<td class="s0" dir="ltr">Jorge Reeves</td>
77+
<td class="s1" dir="ltr">16.52</td>
78+
</tr>
79+
<tr style="height: 20px">
80+
<th id="0R9" style="height: 20px;" class="row-headers-background">
81+
<div class="row-header-wrapper" style="line-height: 20px">10</div>
82+
</th>
83+
<td class="s0" dir="ltr">Leroy Morrow</td>
84+
<td class="s1" dir="ltr">51.24</td>
85+
</tr>
86+
<tr style="height: 20px">
87+
<th id="0R10" style="height: 20px;" class="row-headers-background">
88+
<div class="row-header-wrapper" style="line-height: 20px">11</div>
89+
</th>
90+
<td class="s0" dir="ltr">Ashlyn Crawford</td>
91+
<td class="s1" dir="ltr">7.25</td>
92+
</tr>
93+
<tr style="height: 20px">
94+
<th id="0R11" style="height: 20px;" class="row-headers-background">
95+
<div class="row-header-wrapper" style="line-height: 20px">12</div>
96+
</th>
97+
<td class="s0" dir="ltr">Yasmine Hampton</td>
98+
<td class="s1" dir="ltr">38.42</td>
99+
</tr>
100+
</tbody>
101+
</table>
102+
</div>
Binary file not shown.

0 commit comments

Comments
 (0)