我是第一次尝试使用Passive View实现MVP,但我对于谁在这种模式中通知谁有点困惑。我了解视图会通知演示者是否更改,演示者会反过来通知其他人(其他视图和模型)。
现在,在我的情况下,我有多个视图,而且我还有一个可以在UI之外进行更改的模型。可能会发生以下两种情况:
查看[i]已更改并通知Presenter。 Presenter需要通知所有其他视图和模型,但不能通知View [i]。此外,View和Model都不会向Presenter发送更改通知,即使它们刚被修改(否则会有无限循环的事件)。
模型已更改并通知Presenter。 Presenter需要通知所有视图,但不能通知Model。但是没有一个视图可以向Presenter发送更改通知,即使它刚被修改。
主持人如何通知谁?模型如何知道是否需要发送更改通知?毕竟,它只是被修改了,但它不一定知道由谁。
一种可能性是让每个人(模型,视图和演示者)自由发送更改通知,但是存储对最初在通知内触发更改的对象的引用(从而将通知封装在事件对象中)。如果对象不是更改的原始触发器,则每个对象仅发送通知。但是有更简单,更清洁的方式吗?
答案 0 :(得分:1)
有几种方法可以解决这个问题,但我建议的两种方法是Mediator Pattern或某种类型的Event Aggregator。
Mediator模式背后的想法是,它允许您封装对象集合在特定场景中应该如何交互,同时保持它们彼此无知。
这样的事情:
public class MyPresenterOne{
public event EventHandler OnFoo;
}
public class MyPresenterTwo{
public void DoStuff(){
//Something interesting
}
}
public class MyMediator{
public MyMediator(MyPresenterOne p1, MyPresenterTwo p2){
p1.OnFoo += (o, e) => p2.DoStuff();
}
}
事件聚合器是一种松散耦合的发布/订阅范例,您不是真正在侦听事件,而是在发送消息。一方记录对某种消息的兴趣,但并不真正关心它来自哪里。
public class MyPresenterOne{
public MyPresenterOne(){
EventAggregator.Publish("OnFoo");
}
}
public class MyPresenterTwo{
public MyPresenterTwo(){
EventAggregator.Subscribe("OnFoo", () => {
//Something interesting
});
}
}
介体更容易实现,目的非常明确,但它确实需要对所涉及的各种组件有深入的了解。我们的想法是让调解员专注于特定的构图场景,而不是让一个巨大的调解员。
Pub / Sub范例非常优雅,可以很好地保持组件松散耦合,但需要更多地考虑发布什么类型的消息。