File tree Expand file tree Collapse file tree 7 files changed +164
-0
lines changed
patterns/observer/open_close_editor_events Expand file tree Collapse file tree 7 files changed +164
-0
lines changed Original file line number Diff line number Diff line change 1+ # Observer pattern
2+ Observer is a behavioral design pattern that lets you define a subscription mechanism to notify
3+ multiple objects about any events that happen to the object they’re observing.
4+
5+ ## Editor example
6+ In this example, the Observer pattern lets the text editor object notify other service objects about
7+ changes in its state.
8+
9+ More detailed explanation on [ RefactoringGuru] ( https://refactoring.guru/design-patterns/observer?#pseudocode ) .
10+
11+ ### Origin source code:
12+ This example rewrite from [ java example] ( https://github.com/RefactoringGuru/design-patterns-java/tree/master/src/refactoring_guru/observer/example ) .
13+
14+ ### Diagram:
15+ ![ image] ( https://user-images.githubusercontent.com/8049534/150955865-7fbb29f3-ed48-4317-a356-cbb9cc79ed11.png )
16+
17+ ### Client code:
18+ ``` dart
19+ void main() {
20+ final editor = Editor();
21+ editor.events
22+ ..subscribe(
23+ 'open',
24+ LogOpenListener('log.txt'),
25+ )
26+ ..subscribe(
27+ 'save',
28+ EmailNotificationListener('admin@example.com'),
29+ );
30+
31+ try {
32+ editor.openFile('test.txt');
33+ editor.saveFile();
34+ } catch (e) {
35+ print(e);
36+ }
37+ }
38+ ```
39+
40+ ** Output:**
41+ ```
42+ Save to log "log.txt": Someone has performed "open" operation with the following file: "test.txt"
43+ Email to "admin@example.com": Someone has performed "save" operation with the following file: "test.txt"
44+ ```
Original file line number Diff line number Diff line change 1+ import 'dart:io' ;
2+
3+ import '../event_manager/event_manager.dart' ;
4+
5+ class Editor {
6+ final events = EventManager (['open' , 'save' ]);
7+
8+ File ? _file;
9+
10+ void openFile (String filePath) {
11+ _file = File (filePath);
12+ events.notify ("open" , _file! );
13+ }
14+
15+ void saveFile () {
16+ if (_file == null ) {
17+ throw Exception ('Please open a file first.' );
18+ }
19+
20+ events.notify ('save' , _file! );
21+ }
22+ }
Original file line number Diff line number Diff line change 1+ import 'dart:io' ;
2+
3+ import '../listeners/event_listener.dart' ;
4+
5+ class EventManager {
6+ final _listeners = < String , List <EventListener >> {};
7+
8+ EventManager (List <String > operations) {
9+ for (final operation in operations) {
10+ _listeners[operation] = [];
11+ }
12+ }
13+
14+ void subscribe (String eventType, EventListener listener) {
15+ _usersBy (eventType).add (listener);
16+ }
17+
18+ void unsubscribe (String eventType, EventListener listener) {
19+ _usersBy (eventType).remove (listener);
20+ }
21+
22+ void notify (String eventType, File file) {
23+ final users = _usersBy (eventType);
24+ for (final listener in users) {
25+ listener.update (eventType, file);
26+ }
27+ }
28+
29+ List <EventListener > _usersBy (String eventType) {
30+ final users = _listeners[eventType];
31+
32+ if (users == null ) {
33+ throw UnsupportedError ('Event type "$eventType " do not support.' );
34+ }
35+
36+ return users;
37+ }
38+ }
Original file line number Diff line number Diff line change 1+ import 'dart:io' ;
2+
3+ import 'event_listener.dart' ;
4+
5+ class EmailNotificationListener implements EventListener {
6+ String email;
7+
8+ EmailNotificationListener (this .email);
9+
10+ @override
11+ void update (String eventType, File file) {
12+ print ('Email to "$email ": '
13+ 'Someone has performed "$eventType " '
14+ 'operation with the following file: "${file .path }"' );
15+ }
16+ }
Original file line number Diff line number Diff line change 1+ import 'dart:io' ;
2+
3+ abstract class EventListener {
4+ void update (String eventType, File file);
5+ }
Original file line number Diff line number Diff line change 1+ import 'dart:io' ;
2+
3+ import 'event_listener.dart' ;
4+
5+ class LogOpenListener implements EventListener {
6+ File logFile;
7+
8+ LogOpenListener (String logFileName) : logFile = File (logFileName);
9+
10+ @override
11+ void update (String eventType, File file) {
12+ print ('Save to log "${logFile .path }": '
13+ 'Someone has performed "$eventType " '
14+ 'operation with the following file: "${file .path }"' );
15+ }
16+ }
Original file line number Diff line number Diff line change 1+ import 'editor/editor.dart' ;
2+ import 'listeners/email_notification_listener.dart' ;
3+ import 'listeners/log_open_listener.dart' ;
4+
5+ void main () {
6+ final editor = Editor ();
7+ editor.events
8+ ..subscribe (
9+ 'open' ,
10+ LogOpenListener ('log.txt' ),
11+ )
12+ ..subscribe (
13+ 'save' ,
14+ EmailNotificationListener ('admin@example.com' ),
15+ );
16+
17+ try {
18+ editor.openFile ('test.txt' );
19+ editor.saveFile ();
20+ } catch (e) {
21+ print (e);
22+ }
23+ }
You can’t perform that action at this time.
0 commit comments