diff --git a/CHANGELOG.md b/CHANGELOG.md index 31bae48..63a03ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.36.0 +- Add iterator pattern: Github Commit. + ## 0.35.0 - Add conceptual command pattern. diff --git a/README.md b/README.md index 0fe776b..4a68810 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ It contains **Dart** examples for all classic **GoF** design patterns. - [x] **Chain of Responsibility** - [[Server Middleware](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/chain_of_responsibility/server_middleware)] - [x] **Command** - [[Conceptual](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/command/conceptual)] [[Text Editor](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/command/text_editor)] - [x] **Interpreter** - [[Conceptual](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/interpreter/conceptual)] - - [ ] **Iterator** + - [x] **Iterator** - [[Github Commit](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/iterator/github_commit)] - [x] **Mediator** - [[Conceptual](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/mediator/conceptual)] - [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)] - [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)] diff --git a/patterns/iterator/github_commit/README.md b/patterns/iterator/github_commit/README.md new file mode 100644 index 0000000..0a79ffc --- /dev/null +++ b/patterns/iterator/github_commit/README.md @@ -0,0 +1,44 @@ +# Template Method Pattern +Iterator is a behavioral design pattern that lets you traverse elements of a collection without +exposing its underlying representation (list, stack, tree, etc.). + +Tutorial: [here](https://refactoring.guru/design-patterns/iterator). + +## Diagram: +![image](https://user-images.githubusercontent.com/8049534/183165928-7274e761-09e3-48ce-b9c1-41d552fa1f1a.png) + + +### Client code: +```dart +void main() async { + final GitHubRepo gitHubRepo = await GitHubLoader.get( + userName: 'RefactoringGuru', + repoName: 'design-patterns-dart', + ); + + print( + 'Iterate last 10 commits.' + '\n----------------------------', + ); + + for (Commit commit in gitHubRepo.commitIterator()) { + print(commit.message); + } +} +``` + +### Output: +``` +Iterate last 10 commits. +---------------------------- +Merge pull request #74 from ilopX/fix-conceptual-command-pattern-folder-name Fix conceptual command pattern folder name +Fix conceptual command pattern folder name. +Merge pull request #73 from ilopX/add-conceptual-command-pattern Add conceptual command pattern +Bump version 0.35.0. +Add README. +Impl conceptual command pattern. +Merge pull request #72 from ilopX/add-singleton-pattern Add singleton pattern. +Bump version 0.34.0. +Add README. +``` + diff --git a/patterns/iterator/github_commit/github/commit.dart b/patterns/iterator/github_commit/github/commit.dart new file mode 100644 index 0000000..88e7e43 --- /dev/null +++ b/patterns/iterator/github_commit/github/commit.dart @@ -0,0 +1,5 @@ +class Commit { + String message; + + Commit(this.message); +} diff --git a/patterns/iterator/github_commit/github/github_loader.dart b/patterns/iterator/github_commit/github/github_loader.dart new file mode 100644 index 0000000..8a40889 --- /dev/null +++ b/patterns/iterator/github_commit/github/github_loader.dart @@ -0,0 +1,27 @@ +import 'dart:convert'; +import 'dart:io'; +import '../pattern/github_repo.dart'; + +class GitHubLoader { + static Future get({required userName, required repoName}) async { + final url = Uri.http( + 'api.github.com', + 'repos/$userName/$repoName/commits', + {'per_page': '10'}, + ); + final json = await _loadCommits(url); + return GitHubRepo(json); + } + + static Future> _loadCommits(Uri url) async { + final client = HttpClient(); + try { + final response = await client.getUrl(url); + final request = await response.close(); + final content = await request.transform(utf8.decoder).join(); + return jsonDecode(content); + } finally { + client.close(); + } + } +} diff --git a/patterns/iterator/github_commit/main.dart b/patterns/iterator/github_commit/main.dart new file mode 100644 index 0000000..9df54e9 --- /dev/null +++ b/patterns/iterator/github_commit/main.dart @@ -0,0 +1,19 @@ +import 'github/commit.dart'; +import 'github/github_loader.dart'; +import 'pattern/github_repo.dart'; + +void main() async { + final GitHubRepo gitHubRepo = await GitHubLoader.get( + userName: 'RefactoringGuru', + repoName: 'design-patterns-dart', + ); + + print( + 'Iterate last 10 commits.' + '\n----------------------------', + ); + + for (Commit commit in gitHubRepo.commitIterator()) { + print(commit.message); + } +} diff --git a/patterns/iterator/github_commit/pattern/github_repo.dart b/patterns/iterator/github_commit/pattern/github_repo.dart new file mode 100644 index 0000000..df8377c --- /dev/null +++ b/patterns/iterator/github_commit/pattern/github_repo.dart @@ -0,0 +1,16 @@ +import '../github/commit.dart'; + +class GitHubRepo { + GitHubRepo(this._json); + + Iterable commitIterator() sync* { + for (final jsonCommit in _json) { + var message = jsonCommit['commit']['message'] as String; + message = message.replaceAll(RegExp(r'\n+'), ' '); + + yield Commit(message); + } + } + + final List _json; +} diff --git a/pubspec.yaml b/pubspec.yaml index 76f88a7..fceac9c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: design_patterns_dart description: Dart examples for all classic GoF design patterns. -version: 0.35.0 +version: 0.36.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