我有一个解决方案,将项目集合从源传递给演示者。当源更新时,我希望能够通知演示者显示新结果。
我想到的是创建一个 ChangeNotification 类,将其与结果一起传递,并让该类通知演示者。现在,据我所知,这可以通过两种方式实现,ChangeNotification 可以具有演示者订阅的事件,或者它可以具有演示者设置的委托,并且源在不为空时调用。
使用事件的好处是,不仅仅是消费者可以对通知做出反应,并且您可以将反应性扩展连接到它,缺点是您必须管理事件的订阅/取消订阅以进行正确的垃圾收集。委托很简单,但你会失去一些灵活性。
对于这种情况,最优雅的模式是什么?还有其他我没想到的方法吗?
I have a solution where i pass a collection of items from a source to a presenter. When the source is updated I want to be able to notify the presenter to show the new result.
What comes to mind is to make a ChangeNotification class, pass it along with the result and have that class notify the presenter. Now as I see it this can be implemented in two ways, either ChangeNotification can have events that the presenter subscribes to, or it can have delegates that the presenter sets and the source calls if it is not null.
The benefits of using events is that more than consumer can react to the notification and you can hook up reactive extensions to it, the downside is that you have to manage subscribe/desubscribtion of the events for proper garbage collection. Delegates are simple but you lose some flexibility.
What is the most elegant pattern for situation like this? Is there some other way I haven't thought of?
发布评论
评论(3)
如果您有多个观察者,则需要 Events 或 MultipleDelegates。如果您只有一名观察员,并且想要强制执行,则一名代表就足够了。然而,就哪一个最好而言,恕我直言,我认为该活动更加灵活,并且非常适合该模式。 ObservableCollection 和 INotifyPropertyChanged 是基于事件的实现。顺便说一句,为 tbischel +1 引用这些类。
If you will have multiple observers, Events or MultipleDelegates would be required. If you will only have one observer, and want to enforce that, a delegate would suffice. However, in terms of which is best, IMHO I would say the event is more flexible and lends itself very well to the pattern. The ObservableCollection and INotifyPropertyChanged are event based implementations. By the way, +1 to tbischel for the references to these classes.
此场景有两种内置模式。
首先,您可以实现 INotifyPropertyChanged 接口。如果您想通知演示者集合中对象本身属性的更改,这会更好。 (或者源对象本身,如果那是发生变化的地方)。
第二种方法是向演示者传递一个包含您的对象的 ObservableCollection。如果您想通知演示者集合中已添加或删除了某个项目,则此方法会更好。两者都是事件驱动模型,任何订阅者都可以加入。
编辑:底层模式是 "Observer" 模式...您可以推出您的如果您需要自己的版本,请记下详细信息。
There are two built in patterns for this scenerio.
First, you could implement the INotifyPropertyChanged interface. This is better if you want to notify the presenter of changes to properties of the objects themselves in the collection. (or the source object itself, if that is where changes occur).
The second is to pass your presenter an ObservableCollection containing your objects. This is better if you want to notify the presenter that an item has been added or removed from the collection. Both are event driven models that any subscriber could hook into.
Edit: The underlying pattern is the "Observer" pattern... you can roll out your own version if you want, you have the details down.
我同意其他答案,即 INotifyPropertyChanged、INotifyCollectionChanged 和其他相关接口是首先要转向的属性,但我想添加第三个选项,即实现观察者模式。如果您不熟悉这种模式,这就是 Java 如何通过所谓的 事件监听器。尽管这种模式没有理由不能在 C# 中采用,但在某些情况下,它可能提供比使用事件和委托更优雅的解决方案,特别是当可能有多个协调事件通常都由相关方订阅时。
另一种选择是从 DependencyObject 派生并实现 DependencyProperties,以便获取内置且针对 WPF 优化的更改通知。我倾向于不走这条路,因为我不喜欢拥有特定基类的要求,但有一些很好的论据说明为什么它有时是正确的选择,事实上一些 MVVM 框架甚至使用它作为更改通知的基础对于 ViewModel 类也是如此。
I agree with the other answers that INotifyPropertyChanged, INotifyCollectionChanged and other related interfaces are property the first place to turn but I wanted to add in third option which would be to implement the observer pattern. If your are not familiar with this pattern, it is how Java achieves it's event functionality through what are called event listeners. There is no reason why this pattern cannot be adopted in C# though and in some cases it may provide a more elegant solution than the use of events and delegate especially when there may be several coordinated events that are generally all subscribed to by an interested party.
Another option too is deriving from DependencyObject and implementing DependencyProperties in order to get the change notifications that are built-in and that are optimized for WPF. I tend not to go this route because I don't like the requirement of having a specific base class but there are some good arguments for why it is sometimes the right choice and in fact some MVVM frameworks even use it as the basis of change notifications for ViewModel classes too.