forked from lpxxn/rust-design-pattern
-
Notifications
You must be signed in to change notification settings - Fork 0
/
observer.rs
61 lines (53 loc) · 1.48 KB
/
observer.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//! Observer is a behavioral design pattern that allows one objects to notify other objects about changes in their state.
trait IObserver {
fn update(&self);
}
trait ISubject<'a, T: IObserver> {
fn attach(&mut self, observer: &'a T);
fn detach(&mut self, observer: &'a T);
fn notify_observers(&self);
}
struct Subject<'a, T: IObserver> {
observers: Vec<&'a T>,
}
impl<'a, T: IObserver + PartialEq> Subject<'a, T> {
fn new() -> Subject<'a, T> {
Subject {
observers: Vec::new(),
}
}
}
impl<'a, T: IObserver + PartialEq> ISubject<'a, T> for Subject<'a, T> {
fn attach(&mut self, observer: &'a T) {
self.observers.push(observer);
}
fn detach(&mut self, observer: &'a T) {
if let Some(idx) = self.observers.iter().position(|x| *x == observer) {
self.observers.remove(idx);
}
}
fn notify_observers(&self) {
for item in self.observers.iter() {
item.update();
}
}
}
#[derive(PartialEq)]
struct ConcreteObserver {
id: i32,
}
impl IObserver for ConcreteObserver {
fn update(&self) {
println!("Observer id:{} received event!", self.id);
}
}
fn main() {
let mut subject = Subject::new();
let observer_a = ConcreteObserver { id: 1 };
let observer_b = ConcreteObserver { id: 2 };
subject.attach(&observer_a);
subject.attach(&observer_b);
subject.notify_observers();
subject.detach(&observer_b);
subject.notify_observers();
}