From 1c249580b6fb35ecd551048794bc8bfe9a05f521 Mon Sep 17 00:00:00 2001 From: ilopX Date: Thu, 23 Jun 2022 18:25:48 +0300 Subject: [PATCH 1/6] Impl view strategy example. --- patterns/strategy/print_strategy/main.dart | 107 +++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 patterns/strategy/print_strategy/main.dart diff --git a/patterns/strategy/print_strategy/main.dart b/patterns/strategy/print_strategy/main.dart new file mode 100644 index 0000000..a7c58b8 --- /dev/null +++ b/patterns/strategy/print_strategy/main.dart @@ -0,0 +1,107 @@ +import 'dart:io'; +import 'dart:typed_data'; + +void main() { + final byteList = SomeData() + ..add('Hello guru') + ..add(123456789) + ..add(3.1456564984); + + final strFormat = byteList.toStringView(StrViewStrategy()); + final hexFormat = byteList.toStringView(HexViewStrategy()); + final zipFormat = byteList.toStringView(ZipViewStrategy()); + + print(strFormat); + print(hexFormat); + print(zipFormat); +} + +abstract class ViewStrategy { + String out(SomeData byteList); +} + +class HexViewStrategy implements ViewStrategy { + @override + String out(SomeData byteList) { + final buf = StringBuffer(); + + for (final val in byteList.toList()) { + buf.write('${val.toString().padRight(15)}: '); + + if (val is String) { + buf.writeln(_stringToHex(val)); + } else { + buf.writeln(_valueToHex(val, size: 8)); + } + } + + return buf.toString(); + } + + String _stringToHex(String value) { + return value.codeUnits + .map((charCode) => _valueToHex(size: 1, charCode)) + .join(' '); + } + + String _valueToHex(T value, {required int size}) { + late ByteData byteData; + + if (size == 1) { + byteData = ByteData(1)..setInt8(0, value as int); + } else { + byteData = ByteData(size); + if (value is double) { + byteData.setFloat64(0, value); + } else if (value is int) { + byteData.setInt64(0, value); + } + } + + final bytes = byteData.buffer.asUint8List(); + return bytes.map((e) => e.toRadixString(16).padLeft(2, '0')).join(' '); + } +} + +class StrViewStrategy implements ViewStrategy { + @override + String out(SomeData byteList) { + return '${byteList.toList().join(', ')}\n'; + } +} + +class ZipViewStrategy extends StrViewStrategy { + @override + String out(SomeData byteList) { + final codes = super.out(byteList).codeUnits; + final bytes = GZipCodec().encode(codes); + final buf = StringBuffer(); + + var odd = 1; + for (final byte in bytes) { + final hexByte = byte.toRadixString(16).padLeft(2, '0'); + buf.write('$hexByte '); + + if (odd++ % 16 == 0) { + buf.writeln(); + } + } + + return buf.toString(); + } +} + +class SomeData { + String toStringView(ViewStrategy strategy) { + return '${strategy.runtimeType}:\n' + '${strategy.out(this)}'; + } + + void add(dynamic str) { + _buf.add(str); + } + + List toList() => _buf; + + final _buf = []; +} From 999a22835f967c863a5868ab9962afc4cef04055 Mon Sep 17 00:00:00 2001 From: ilopX Date: Fri, 24 Jun 2022 18:05:35 +0300 Subject: [PATCH 2/6] Rename project to "View Strategy". --- patterns/strategy/print_strategy/main.dart | 107 --------------------- patterns/strategy/view_strategy/main.dart | 19 ++++ 2 files changed, 19 insertions(+), 107 deletions(-) delete mode 100644 patterns/strategy/print_strategy/main.dart create mode 100644 patterns/strategy/view_strategy/main.dart diff --git a/patterns/strategy/print_strategy/main.dart b/patterns/strategy/print_strategy/main.dart deleted file mode 100644 index a7c58b8..0000000 --- a/patterns/strategy/print_strategy/main.dart +++ /dev/null @@ -1,107 +0,0 @@ -import 'dart:io'; -import 'dart:typed_data'; - -void main() { - final byteList = SomeData() - ..add('Hello guru') - ..add(123456789) - ..add(3.1456564984); - - final strFormat = byteList.toStringView(StrViewStrategy()); - final hexFormat = byteList.toStringView(HexViewStrategy()); - final zipFormat = byteList.toStringView(ZipViewStrategy()); - - print(strFormat); - print(hexFormat); - print(zipFormat); -} - -abstract class ViewStrategy { - String out(SomeData byteList); -} - -class HexViewStrategy implements ViewStrategy { - @override - String out(SomeData byteList) { - final buf = StringBuffer(); - - for (final val in byteList.toList()) { - buf.write('${val.toString().padRight(15)}: '); - - if (val is String) { - buf.writeln(_stringToHex(val)); - } else { - buf.writeln(_valueToHex(val, size: 8)); - } - } - - return buf.toString(); - } - - String _stringToHex(String value) { - return value.codeUnits - .map((charCode) => _valueToHex(size: 1, charCode)) - .join(' '); - } - - String _valueToHex(T value, {required int size}) { - late ByteData byteData; - - if (size == 1) { - byteData = ByteData(1)..setInt8(0, value as int); - } else { - byteData = ByteData(size); - if (value is double) { - byteData.setFloat64(0, value); - } else if (value is int) { - byteData.setInt64(0, value); - } - } - - final bytes = byteData.buffer.asUint8List(); - return bytes.map((e) => e.toRadixString(16).padLeft(2, '0')).join(' '); - } -} - -class StrViewStrategy implements ViewStrategy { - @override - String out(SomeData byteList) { - return '${byteList.toList().join(', ')}\n'; - } -} - -class ZipViewStrategy extends StrViewStrategy { - @override - String out(SomeData byteList) { - final codes = super.out(byteList).codeUnits; - final bytes = GZipCodec().encode(codes); - final buf = StringBuffer(); - - var odd = 1; - for (final byte in bytes) { - final hexByte = byte.toRadixString(16).padLeft(2, '0'); - buf.write('$hexByte '); - - if (odd++ % 16 == 0) { - buf.writeln(); - } - } - - return buf.toString(); - } -} - -class SomeData { - String toStringView(ViewStrategy strategy) { - return '${strategy.runtimeType}:\n' - '${strategy.out(this)}'; - } - - void add(dynamic str) { - _buf.add(str); - } - - List toList() => _buf; - - final _buf = []; -} diff --git a/patterns/strategy/view_strategy/main.dart b/patterns/strategy/view_strategy/main.dart new file mode 100644 index 0000000..fe343f4 --- /dev/null +++ b/patterns/strategy/view_strategy/main.dart @@ -0,0 +1,19 @@ +import 'pattern/byte_context.dart'; +import 'strategies/hex_view_strategy.dart'; +import 'strategies/str_view_strategy.dart'; +import 'strategies/zip_view_strategy.dart'; + +void main() { + final byteList = ByteContext() + ..add('Hello guru') + ..add(123456789) + ..add(3.1456564984); + + final strFormat = byteList.toStringView(StrViewStrategy()); + final hexFormat = byteList.toStringView(HexViewStrategy()); + final zipFormat = byteList.toStringView(ZipViewStrategy()); + + print(strFormat); + print(hexFormat); + print(zipFormat); +} From 61eb1c43383280c48d872b997e881308042508cd Mon Sep 17 00:00:00 2001 From: ilopX Date: Fri, 24 Jun 2022 18:06:41 +0300 Subject: [PATCH 3/6] Split project into separate files. --- .../view_strategy/pattern/byte_context.dart | 16 +++++++ .../view_strategy/pattern/view_strategy.dart | 5 ++ .../strategies/hex_view_strategy.dart | 47 +++++++++++++++++++ .../strategies/str_view_strategy.dart | 9 ++++ .../strategies/zip_view_strategy.dart | 25 ++++++++++ 5 files changed, 102 insertions(+) create mode 100644 patterns/strategy/view_strategy/pattern/byte_context.dart create mode 100644 patterns/strategy/view_strategy/pattern/view_strategy.dart create mode 100644 patterns/strategy/view_strategy/strategies/hex_view_strategy.dart create mode 100644 patterns/strategy/view_strategy/strategies/str_view_strategy.dart create mode 100644 patterns/strategy/view_strategy/strategies/zip_view_strategy.dart diff --git a/patterns/strategy/view_strategy/pattern/byte_context.dart b/patterns/strategy/view_strategy/pattern/byte_context.dart new file mode 100644 index 0000000..962d45c --- /dev/null +++ b/patterns/strategy/view_strategy/pattern/byte_context.dart @@ -0,0 +1,16 @@ +import 'view_strategy.dart'; + +class ByteContext { + String toStringView(ViewStrategy strategy) { + return '${strategy.runtimeType}:\n' + '${strategy.out(this)}'; + } + + void add(dynamic value) { + _buf.add(value); + } + + List toList() => _buf; + + final _buf = []; +} diff --git a/patterns/strategy/view_strategy/pattern/view_strategy.dart b/patterns/strategy/view_strategy/pattern/view_strategy.dart new file mode 100644 index 0000000..4b785ec --- /dev/null +++ b/patterns/strategy/view_strategy/pattern/view_strategy.dart @@ -0,0 +1,5 @@ +import 'byte_context.dart'; + +abstract class ViewStrategy { + String out(ByteContext byteList); +} diff --git a/patterns/strategy/view_strategy/strategies/hex_view_strategy.dart b/patterns/strategy/view_strategy/strategies/hex_view_strategy.dart new file mode 100644 index 0000000..408d276 --- /dev/null +++ b/patterns/strategy/view_strategy/strategies/hex_view_strategy.dart @@ -0,0 +1,47 @@ +import 'dart:typed_data'; + +import '../pattern/byte_context.dart'; +import '../pattern/view_strategy.dart'; + +class HexViewStrategy implements ViewStrategy { + @override + String out(ByteContext byteList) { + final buf = StringBuffer(); + + for (final val in byteList.toList()) { + buf.write('${val.toString().padRight(15)}: '); + + if (val is String) { + buf.writeln(_stringToHex(val)); + } else { + buf.writeln(_valueToHex(val, size: 8)); + } + } + + return buf.toString(); + } + + String _stringToHex(String value) { + return value.codeUnits + .map((charCode) => _valueToHex(size: 1, charCode)) + .join(' '); + } + + String _valueToHex(T value, {required int size}) { + late ByteData byteData; + + if (size == 1) { + byteData = ByteData(1)..setInt8(0, value as int); + } else { + byteData = ByteData(size); + if (value is double) { + byteData.setFloat64(0, value); + } else if (value is int) { + byteData.setInt64(0, value); + } + } + + final bytes = byteData.buffer.asUint8List(); + return bytes.map((e) => e.toRadixString(16).padLeft(2, '0')).join(' '); + } +} diff --git a/patterns/strategy/view_strategy/strategies/str_view_strategy.dart b/patterns/strategy/view_strategy/strategies/str_view_strategy.dart new file mode 100644 index 0000000..b9aa9bb --- /dev/null +++ b/patterns/strategy/view_strategy/strategies/str_view_strategy.dart @@ -0,0 +1,9 @@ +import '../pattern/byte_context.dart'; +import '../pattern/view_strategy.dart'; + +class StrViewStrategy implements ViewStrategy { + @override + String out(ByteContext byteList) { + return '${byteList.toList().join(', ')}\n'; + } +} diff --git a/patterns/strategy/view_strategy/strategies/zip_view_strategy.dart b/patterns/strategy/view_strategy/strategies/zip_view_strategy.dart new file mode 100644 index 0000000..7e78645 --- /dev/null +++ b/patterns/strategy/view_strategy/strategies/zip_view_strategy.dart @@ -0,0 +1,25 @@ +import 'dart:io'; + +import '../pattern/byte_context.dart'; +import 'str_view_strategy.dart'; + +class ZipViewStrategy extends StrViewStrategy { + @override + String out(ByteContext byteList) { + final codes = super.out(byteList).codeUnits; + final bytes = GZipCodec().encode(codes); + final buf = StringBuffer(); + + var odd = 1; + for (final byte in bytes) { + final hexByte = byte.toRadixString(16).padLeft(2, '0'); + buf.write('$hexByte '); + + if (odd++ % 16 == 0) { + buf.writeln(); + } + } + + return buf.toString(); + } +} From 1e52f596a888bede08ac8b29c384042fd584b6b7 Mon Sep 17 00:00:00 2001 From: ilopX Date: Fri, 24 Jun 2022 18:07:00 +0300 Subject: [PATCH 4/6] Add project README. --- patterns/strategy/view_strategy/README.md | 43 +++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 patterns/strategy/view_strategy/README.md diff --git a/patterns/strategy/view_strategy/README.md b/patterns/strategy/view_strategy/README.md new file mode 100644 index 0000000..ad2abd8 --- /dev/null +++ b/patterns/strategy/view_strategy/README.md @@ -0,0 +1,43 @@ +# Strategy Pattern +Strategy is a behavioral design pattern that lets you define a family of algorithms, put each of +them into a separate class, and make their objects interchangeable. + +Tutorial: [here](https://refactoring.guru/design-patterns/strategy). + +## Diagram: +![image](https://user-images.githubusercontent.com/8049534/175562829-c91fbb12-50ac-4373-a33f-900527383a6c.png) + +## Client code: +```dart +void main() { + final byteList = ByteContext() + ..add('Hello guru') + ..add(123456789) + ..add(3.1456564984); + + final strFormat = byteList.toStringView(StrViewStrategy()); + final hexFormat = byteList.toStringView(HexViewStrategy()); + final zipFormat = byteList.toStringView(ZipViewStrategy()); + + print(strFormat); + print(hexFormat); + print(zipFormat); +} +``` + +### Output: +``` +StrViewStrategy: +Hello guru, 123456789, 3.1456564984 + +HexViewStrategy: +Hello guru : 48 65 6c 6c 6f 20 67 75 72 75 +123456789 : 00 00 00 00 07 5b cd 15 +3.1456564984 : 40 09 2a 4d f4 48 9f 7e + +ZipViewStrategy: +1f 8b 08 00 00 00 00 00 00 0a f3 48 cd c9 c9 57 +48 2f 2d 2a d5 51 30 34 32 36 31 35 33 b7 b0 d4 +51 30 d6 33 04 32 4d cd 4c 2c 2d 4c b8 00 d4 70 +cf ee 24 00 00 00 +``` From 8b8de853630a39d39f7a854ef816ed76a55c4cbd Mon Sep 17 00:00:00 2001 From: ilopX Date: Fri, 24 Jun 2022 18:07:17 +0300 Subject: [PATCH 5/6] Update main README. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a93a531..ae35cd7 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ It contains **Dart** examples for all classic **GoF** design patterns. - [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** - [[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)] + - [X] **Strategy** [[View Strategy](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/strategy/view_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)] From 1295176a58d25641e9870b5f0a6dddd4cb937b7e Mon Sep 17 00:00:00 2001 From: ilopX Date: Fri, 24 Jun 2022 18:07:39 +0300 Subject: [PATCH 6/6] Bump version 0.30.0. --- CHANGELOG.md | 3 +++ pubspec.yaml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fea0c92..72f9145 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.30.0 +- Add strategy pattern: View Strategy. + ## 0.29.0 - Add conceptual visitor pattern. diff --git a/pubspec.yaml b/pubspec.yaml index 18c1e3d..ca5e20d 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.29.0 +version: 0.30.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