3

我第一次尝试使用 Passive View 实现 MVP,但我有点困惑谁在这种模式下通知谁。我知道如果视图发生更改,视图会通知演示者,而演示者又会通知其他所有人(其他视图和模型)。

现在,就我而言,我有多个视图,而且我还有一个可以在 UI 之外更改的模型。可能会发生以下两种情况:

  1. View[i] 发生变化并通知 Presenter。Presenter 需要通知所有其他视图和模型,但不需要通知 View[i]。此外,视图和模型都不能向 Presenter 发送更改通知,即使它们刚刚被修改(否则会出现无限循环的事件)。

  2. 模型发生变化并通知 Presenter。Presenter 需要通知所有视图,而不是 Model。但是即使它刚刚被修改,任何视图都不会向 Presenter 发送更改通知。

主持人将如何通知谁,谁不通知?模型如何知道它是否需要发送更改通知?毕竟,它只是被修改,但它不一定知道是谁。

一种可能性是让每个人(模型、视图和演示者)自由地发送更改通知,但在通知中存储对最初触发更改的对象的引用(从而将通知封装在事件对象中)。然后,每个对象仅在他不是更改的原始触发器时才发送通知。但是有没有更简单、更清洁的方法呢?

4

1 回答 1

1

有几种方法可以解决这个问题,但我推荐的两种方法是Mediator Pattern,或者某种类型的Event Aggregator

中介者模式背后的想法是,它允许您封装对象集合在特定场景中应如何交互,同时保持它们彼此不知道。

像这样的东西:

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 范式非常优雅,可以很好地保持组件松散耦合,但在发布什么样的消息方面需要更多的思考。

于 2012-12-08T05:39:03.927 回答