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.30.0
- Add strategy pattern: View Strategy.

## 0.29.0
- Add conceptual visitor pattern.

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
43 changes: 43 additions & 0 deletions patterns/strategy/view_strategy/README.md
Original file line number Diff line number Diff line change
@@ -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
```
19 changes: 19 additions & 0 deletions patterns/strategy/view_strategy/main.dart
Original file line number Diff line number Diff line change
@@ -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);
}
16 changes: 16 additions & 0 deletions patterns/strategy/view_strategy/pattern/byte_context.dart
Original file line number Diff line number Diff line change
@@ -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 = <dynamic>[];
}
5 changes: 5 additions & 0 deletions patterns/strategy/view_strategy/pattern/view_strategy.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import 'byte_context.dart';

abstract class ViewStrategy {
String out(ByteContext byteList);
}
47 changes: 47 additions & 0 deletions patterns/strategy/view_strategy/strategies/hex_view_strategy.dart
Original file line number Diff line number Diff line change
@@ -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>(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(' ');
}
}
Original file line number Diff line number Diff line change
@@ -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';
}
}
25 changes: 25 additions & 0 deletions patterns/strategy/view_strategy/strategies/zip_view_strategy.dart
Original file line number Diff line number Diff line change
@@ -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();
}
}
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.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
Expand Down