Skip to content

Commit 84bc8f0

Browse files
authored
Merge pull request #41 from ilopX/add-factory-method-pattern
Add factory method pattern.
2 parents fb18f70 + 0046ad5 commit 84bc8f0

File tree

11 files changed

+162
-3
lines changed

11 files changed

+162
-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.20.0
2+
- Add "Conceptual Dialog Factory" example.
3+
14
## 0.19.0
25
- Add "Conceptual Gui Factory" example.
36

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ It contains **Dart** examples for all classic **GoF** design patterns.
44

55
# Implementation checklist:
66
- [ ] **Creation**
7-
- [ ] **Abstract Factory** [[Conceptual Gui Factory](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/abstract_factory/conceptual_gui_factory)]
7+
- [x] **Abstract Factory** [[Conceptual Gui Factory](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/abstract_factory/conceptual_gui_factory)]
88
- [x] **Builder** - [[Color Text Format](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/builder/color_text_format)]
9-
- [ ] **Factory Method**
9+
- [x] **Factory Method** [[Conceptual Platform Dialog](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/factory_method/conceptual_platform_dialog)]
1010
- [x] **Prototype** - [[Shapes](https://github.com/RefactoringGuru/design-patterns-dart/tree/main/patterns/prototype/shapes)]
1111
- [ ] **Singleton**
1212
- [ ] **Behavioral**
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Abstract Factory pattern
2+
Factory Method is a creational design pattern that provides an interface for creating objects in a
3+
superclass, but allows subclasses to alter the type of objects that will be created.
4+
5+
Tutorial: [here](https://refactoring.guru/design-patterns/factory-method).
6+
7+
### About example.
8+
This the very conceptual example rewrite from original source code [java example](https://github.com/RefactoringGuru/design-patterns-java/tree/main/src/refactoring_guru/factory_method/example)
9+
10+
### Diagram:
11+
![image](https://user-images.githubusercontent.com/8049534/166105090-a2b490fe-3e3e-44f1-a781-9777023020fb.png)
12+
13+
### Client code:
14+
```dart
15+
late Dialog dialog;
16+
17+
void main() {
18+
configure();
19+
runBusinessLogic();
20+
}
21+
22+
void configure() {
23+
if (Platform.isWindows) {
24+
dialog = WindowsDialog();
25+
} else {
26+
dialog = HtmlDialog();
27+
}
28+
}
29+
30+
void runBusinessLogic() {
31+
dialog.renderWindow();
32+
}
33+
```
34+
35+
### Output:
36+
```
37+
Windows Button
38+
Click! Button says - "Hello World!"
39+
```
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/// EN: Common interface for all buttons.
2+
///
3+
/// RU: Общий интерфейс для всех продуктов.
4+
abstract class Button {
5+
final void Function() onClick;
6+
7+
Button(this.onClick);
8+
9+
void render();
10+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import 'button.dart';
2+
3+
/// EN: HTML button implementation.
4+
///
5+
/// RU: Реализация HTML кнопок.
6+
class HtmlButton extends Button {
7+
HtmlButton(void Function() onClick) : super(onClick);
8+
9+
@override
10+
void render() {
11+
print('<button>Test Button</button>');
12+
onClick();
13+
}
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import 'button.dart';
2+
3+
/// EN: Windows button implementation.
4+
///
5+
/// RU: Реализация нативных кнопок операционной системы.
6+
class WindowsButton extends Button {
7+
WindowsButton(void Function() onClick) : super(onClick);
8+
9+
@override
10+
void render() {
11+
print('Windows Button');
12+
onClick();
13+
}
14+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import '../buttons/button.dart';
2+
3+
abstract class Dialog {
4+
void renderWindow() {
5+
/// EN: ... other code ...
6+
///
7+
/// RU: ... остальной код диалога ...
8+
9+
Button okButton = createButton(() {
10+
print('Click! Button says - "Hello World!"');
11+
});
12+
okButton.render();
13+
}
14+
15+
/// EN: Subclasses will override this method in order to create specific
16+
/// button objects.
17+
///
18+
/// RU: Подклассы будут переопределять этот метод, чтобы создавать конкретные
19+
/// объекты продуктов, разные для каждой фабрики.
20+
Button createButton(void Function() onClick);
21+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import '../buttons/button.dart';
2+
import '../buttons/html_button.dart';
3+
import 'dialog.dart';
4+
5+
/// EN: HTML Dialog will produce HTML buttons.
6+
///
7+
/// RU: HTML-диалог.
8+
class HtmlDialog extends Dialog {
9+
@override
10+
Button createButton(void Function() onClick) => HtmlButton(onClick);
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import '../buttons/button.dart';
2+
import '../buttons/windows_button.dart';
3+
import 'dialog.dart';
4+
5+
/// EN: Windows Dialog will produce Windows buttons.
6+
///
7+
/// RU: Диалог на элементах операционной системы.
8+
class WindowsDialog extends Dialog {
9+
@override
10+
Button createButton(void Function() onClick) => WindowsButton(onClick);
11+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import 'dart:io';
2+
3+
import 'dialogs_factory/dialog.dart';
4+
import 'dialogs_factory/html_dialog.dart';
5+
import 'dialogs_factory/windows_dialog.dart';
6+
7+
late Dialog dialog;
8+
9+
void main() {
10+
configure();
11+
runBusinessLogic();
12+
}
13+
14+
/// EN: The concrete factory is usually chosen depending on configuration or
15+
/// environment options.
16+
///
17+
/// RU: Приложение создаёт определённую фабрику в зависимости от конфигурации
18+
/// или окружения.
19+
void configure() {
20+
if (Platform.isWindows) {
21+
dialog = WindowsDialog();
22+
} else {
23+
dialog = HtmlDialog();
24+
}
25+
}
26+
27+
/// EN: All of the client code should work with factories and products
28+
/// through abstract interfaces. This way it does not care which factory it
29+
/// works with and what kind of product it returns.
30+
///
31+
/// RU: Весь остальной клиентский код работает с фабрикой и продуктами только
32+
/// через общий интерфейс, поэтому для него неважно какая фабрика была
33+
/// создана.
34+
void runBusinessLogic() {
35+
dialog.renderWindow();
36+
}

0 commit comments

Comments
 (0)