Skip to content

Commit 5a92ed8

Browse files
committed
Add Easy Example to Observer
1 parent 57d05a8 commit 5a92ed8

File tree

2 files changed

+271
-0
lines changed

2 files changed

+271
-0
lines changed
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
<h1> Easy Example </h1>
2+
3+
- src: https://refactoring.guru/design-patterns/observer/csharp/example
4+
5+
- Observer is a behavioral design pattern
6+
- that allows some objects to notify other objects about changes in their state.
7+
- The Observer pattern provides a way to subscribe and unsubscribe to and from these events for any object that implements a subscriber interface.
8+
9+
---
10+
11+
- Usage examples:
12+
- especially in the GUI components.
13+
- It provides a way to react to events happening in other objects without coupling to their classes.
14+
15+
---
16+
17+
- Identification:
18+
- The pattern can be recognized if you see a subscription method that stores incoming objects in a list.
19+
- You can confirm the identification,
20+
- if you see some sort of notification method that iterates over objects in that list and calls their “update” method.
21+
22+
```dart
23+
abstract class BaseObserver {
24+
/// Receive update from subject
25+
void Update(BaseSubject subject);
26+
}
27+
```
28+
29+
```dart
30+
abstract class BaseSubject {
31+
// Attach an observer to the subject.
32+
void Attach(BaseObserver observer);
33+
34+
// Detach an observer from the subject.
35+
void Detach(BaseObserver observer);
36+
37+
// Notify all observers about an event.
38+
void Notify();
39+
}
40+
```
41+
42+
```dart
43+
// The Subject owns some important state and notifies observers when the
44+
// state changes.
45+
class Subject implements BaseSubject {
46+
// For the sake of simplicity, the Subject's state, essential to all
47+
// subscribers, is stored in this variable.
48+
int state = 0;
49+
50+
// List of subscribers. In real life, the list of subscribers can be
51+
// stored more comprehensively (categorized by event type, etc.).
52+
List<BaseObserver> _observers = [];
53+
54+
// The subscription management methods.
55+
void Attach(BaseObserver observer) {
56+
print("Subject: Attached an observer.");
57+
_observers.add(observer);
58+
}
59+
60+
void Detach(BaseObserver observer) {
61+
_observers.remove(observer);
62+
print("Subject: Detached an observer.");
63+
}
64+
65+
// Trigger an update in each subscriber.
66+
void Notify() {
67+
print("Subject: Notifying observers...");
68+
69+
for (var observer in _observers) {
70+
observer.Update(this);
71+
}
72+
}
73+
74+
// Usually, the subscription logic is only a fraction of what a Subject
75+
// can really do. Subjects commonly hold some important business logic,
76+
// that triggers a notification method whenever something important is
77+
// about to happen (or after it).
78+
void SomeBusinessLogic() {
79+
print("\nSubject: I'm doing something important.");
80+
state = new math.Random().nextInt(10);
81+
82+
print("Subject: My state has just changed to: $state");
83+
Notify();
84+
}
85+
}
86+
```
87+
88+
```dart
89+
// Concrete Observers react to the updates issued by the Subject they had
90+
// been attached to.
91+
class ConcreteObserverA implements BaseObserver {
92+
void Update(BaseSubject subject) {
93+
if (subject is Subject) {
94+
if (subject.state < 3) {
95+
print("subject is Subject :: (subject.state < 3)");
96+
}
97+
}
98+
print("Not Subject OR Not (subject.state < 3)");
99+
}
100+
}
101+
102+
class ConcreteObserverB implements BaseObserver {
103+
void Update(BaseSubject subject) {
104+
if (subject is Subject) {
105+
print("ConcreteObserverB: Reacted to the event.");
106+
}
107+
}
108+
}
109+
```
110+
111+
```dart
112+
void main() {
113+
// The client code.
114+
var subject = new Subject();
115+
var observerA = new ConcreteObserverA();
116+
subject.Attach(observerA);
117+
118+
var observerB = new ConcreteObserverB();
119+
subject.Attach(observerB);
120+
121+
subject.SomeBusinessLogic();
122+
subject.SomeBusinessLogic();
123+
124+
subject.Detach(observerB);
125+
126+
subject.SomeBusinessLogic();
127+
}
128+
129+
```
130+
131+
```dart
132+
// Output.txt: Execution result
133+
// Subject: Attached an observer.
134+
// Subject: Attached an observer.
135+
136+
// Subject: I'm doing something important.
137+
// Subject: My state has just changed to: 2
138+
// Subject: Notifying observers...
139+
// ConcreteObserverA: Reacted to the event.
140+
// ConcreteObserverB: Reacted to the event.
141+
142+
// Subject: I'm doing something important.
143+
// Subject: My state has just changed to: 1
144+
// Subject: Notifying observers...
145+
// ConcreteObserverA: Reacted to the event.
146+
// Subject: Detached an observer.
147+
148+
// Subject: I'm doing something important.
149+
// Subject: My state has just changed to: 5
150+
// Subject: Notifying observers...
151+
```
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import 'dart:math' as math;
2+
3+
abstract class BaseObserver {
4+
/// Receive update from subject
5+
void Update(BaseSubject subject);
6+
}
7+
8+
abstract class BaseSubject {
9+
// Attach an observer to the subject.
10+
void Attach(BaseObserver observer);
11+
12+
// Detach an observer from the subject.
13+
void Detach(BaseObserver observer);
14+
15+
// Notify all observers about an event.
16+
void Notify();
17+
}
18+
19+
// The Subject owns some important state and notifies observers when the
20+
// state changes.
21+
class Subject implements BaseSubject {
22+
// For the sake of simplicity, the Subject's state, essential to all
23+
// subscribers, is stored in this variable.
24+
int state = 0;
25+
26+
// List of subscribers. In real life, the list of subscribers can be
27+
// stored more comprehensively (categorized by event type, etc.).
28+
List<BaseObserver> _observers = [];
29+
30+
// The subscription management methods.
31+
void Attach(BaseObserver observer) {
32+
print("Subject: Attached an observer.");
33+
_observers.add(observer);
34+
}
35+
36+
void Detach(BaseObserver observer) {
37+
_observers.remove(observer);
38+
print("Subject: Detached an observer.");
39+
}
40+
41+
// Trigger an update in each subscriber.
42+
void Notify() {
43+
print("Subject: Notifying observers...");
44+
45+
for (var observer in _observers) {
46+
observer.Update(this);
47+
}
48+
}
49+
50+
// Usually, the subscription logic is only a fraction of what a Subject
51+
// can really do. Subjects commonly hold some important business logic,
52+
// that triggers a notification method whenever something important is
53+
// about to happen (or after it).
54+
void SomeBusinessLogic() {
55+
print("\nSubject: I'm doing something important.");
56+
state = new math.Random().nextInt(10);
57+
58+
print("Subject: My state has just changed to: $state");
59+
Notify();
60+
}
61+
}
62+
63+
// Concrete Observers react to the updates issued by the Subject they had
64+
// been attached to.
65+
class ConcreteObserverA implements BaseObserver {
66+
void Update(BaseSubject subject) {
67+
if (subject is Subject) {
68+
if (subject.state < 3) {
69+
print("subject is Subject :: (subject.state < 3)");
70+
}
71+
}
72+
print("Not Subject OR Not (subject.state < 3)");
73+
}
74+
}
75+
76+
class ConcreteObserverB implements BaseObserver {
77+
void Update(BaseSubject subject) {
78+
if (subject is Subject) {
79+
print("ConcreteObserverB: Reacted to the event.");
80+
}
81+
}
82+
}
83+
84+
void main() {
85+
// The client code.
86+
var subject = new Subject();
87+
var observerA = new ConcreteObserverA();
88+
subject.Attach(observerA);
89+
90+
var observerB = new ConcreteObserverB();
91+
subject.Attach(observerB);
92+
93+
subject.SomeBusinessLogic();
94+
subject.SomeBusinessLogic();
95+
96+
subject.Detach(observerB);
97+
98+
subject.SomeBusinessLogic();
99+
}
100+
101+
102+
// Output.txt: Execution result
103+
// Subject: Attached an observer.
104+
// Subject: Attached an observer.
105+
106+
// Subject: I'm doing something important.
107+
// Subject: My state has just changed to: 2
108+
// Subject: Notifying observers...
109+
// ConcreteObserverA: Reacted to the event.
110+
// ConcreteObserverB: Reacted to the event.
111+
112+
// Subject: I'm doing something important.
113+
// Subject: My state has just changed to: 1
114+
// Subject: Notifying observers...
115+
// ConcreteObserverA: Reacted to the event.
116+
// Subject: Detached an observer.
117+
118+
// Subject: I'm doing something important.
119+
// Subject: My state has just changed to: 5
120+
// Subject: Notifying observers...

0 commit comments

Comments
 (0)