Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Observer #60

Open
Tracked by #116
JaneSmith opened this issue Sep 10, 2017 · 3 comments
Open
Tracked by #116

Observer #60

JaneSmith opened this issue Sep 10, 2017 · 3 comments
Labels
A-pattern Area: Content about Patterns C-addition Category: Adding new content, something that didn't exist in the repository before

Comments

@JaneSmith
Copy link

Could we get an example of how to implement the Observer pattern, or an alternative solution if that pattern is not a good fit in Rust? Thanks.

@lynnux
Copy link

lynnux commented Sep 22, 2017

I just read an article which implement observer pattern, https://blog.rom1v.com/2017/09/gnirehtet-rewritten-in-rust/, hope it will be conainted in this repo.

@simonsan simonsan added the C-addition Category: Adding new content, something that didn't exist in the repository before label Dec 31, 2020
@simonsan simonsan changed the title Observer pattern Observer Jan 21, 2021
@simonsan simonsan added the A-pattern Area: Content about Patterns label Jan 21, 2021
@simonsan
Copy link
Collaborator

Example taken from: https://github.com/lpxxn/rust-design-pattern/blob/master/behavioral/observer.rs

//! 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();
}

@simonsan
Copy link
Collaborator

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-pattern Area: Content about Patterns C-addition Category: Adding new content, something that didn't exist in the repository before
Projects
None yet
Development

No branches or pull requests

3 participants