我试图将观察者模式应用于Rust。与其他GC语言(如JS或Java)一样,我希望将事件Observable
中的数据引用发送到Observer
。但是由于借用检查器,编译器继续让我头疼。因此,我学会了使用Rc
,但它不允许我改变Observable
中的值,然后我使用RefCell
进行内部可变性,这是我想要的。霍拉我说。但后来我意识到Rc
导致从不同的地方引用一个位置,这使得Observer
上的事件系统过时了。因此,在从Observer
中删除事件方法后,我得到了:
struct Observable<T: Clone> {
value: Rc<RefCell<T>>
}
impl<T: Clone> Observable<T> {
fn new(value: T) -> Observable<T> {
Observable {
value: Rc::new(RefCell::new(value))
}
}
fn set_value(&mut self, value: T) {
*self.value.borrow_mut() = value;
}
fn register(&mut self) -> Observer<T> {
Observer::new(self.value.clone())
}
}
struct Observer<T: Clone> {
value: Rc<RefCell<T>>
}
impl<T: Clone> Observer<T> {
fn new(value: Rc<RefCell<T>>) -> Observer<T> {
Observer {
value
}
}
fn value(&self) -> T {
(*self.value.borrow()).clone()
}
}
从技术角度来看,上面给出的代码代表了一个观察者模式吗?因为否则它对我有用。但只是想知道什么构成观察者模式?
答案 0 :(得分:3)
上面给出的代码代表了一个观察者模式 技术观点?
否
但只是想知道什么构成观察者模式?
我已更新您的代码以模拟观察者模式。
#[allow(unused_variables)]
pub trait Events {
fn on_value(&self, value: &str) {}
}
struct Observable {
value: String,
observers: Vec<Box<Events>>,
}
impl Observable {
fn new(value: &str) -> Observable {
Observable {
value: value.to_owned(),
observers: Vec::new(),
}
}
fn set_value(&mut self, value: &str) {
self.value = value.to_owned();
// send event to observers
for observer in &self.observers {
observer.on_value(value);
}
}
fn register<E: Events + 'static>(&mut self, observer: E) {
self.observers.push(Box::new(observer));
}
}
struct Observer;
impl Events for Observer {
fn on_value(&self, value: &str) {
println!("received value: {:?}", value);
}
}
fn main() {
let mut observable = Observable::new("initial value");
observable.register(Observer);
observable.set_value("updated value");
}
Observable 是主题,它维护着一个观察者的列表。 设置新值时,Observable会通知观察者。
答案 1 :(得分:1)
不,它不代表观察者模式。
观察者模式是一种软件设计模式,其中一个称为主体的对象维护其依赖者列表,称为观察者,并通常通过调用其中一种方法自动通知它们任何状态变化。
您的实施中缺少的是观察者在观察到变化时没有收到通知。