views:

23

answers:

2

Let's say I have a GUI with multiple types of viewers of user objects. For example, a tree view, a list view and a diagram view. The three views show the same objects. If a user deletes an object from one view, I would like to fire off an event to notify the other two views. I currently do this by exposing an event on the object itself. So if the object is deleted from View 1, View 1 will call delete on the object, which will then fire an event to the subscribers (all 3 views). Each subscriber has the chance to cancel the deletion.

There are a few problems as I see it. If a subscriber cancels a deletion after another subscriber has already approved of the deletion, then I have to instruct those subscribers to undo the deletion.

Are there any good patterns to implement this kind of common scenario?

+2  A: 

If an object is to be deleted from all views, or no view at all

  1. Ask every subscriber if it's ok to delete the item; if yes:
  2. Issue a "delete item" call to remove the object from the source, perform a soft delete or whatever you'd like
  3. Update each view. This would be the observer part, listen for a "object deleted" call and take appropriate actions, for example manually remove the now deleted object from each view

If you always want the user to be able to delete the object from its own view:

  1. Step 2. from above, with the addition that it's only been deleted either for 1) the user; or 2) that user in that view
  2. Step 1. from above, and continue.. (might be skipped, depending on how much you'd like the views to be coherent)
chelmertz
+2  A: 

The twist here is that each subscriber has the chance to cancel the deletion. Normally, when you use the words "view" and "subscribe", it means that you are being passive and just reacting to what you see.

That doesn't mean that what you're trying to do is impossible, but it's definitely tricky. For example, you could try to do a sort of two-phase commit, where you mark the object is deleted and then wait for all of the viewers to acknowledge the deletion before really removing the object. (This is basically the "ask every subscriber if it's OK to delete the item" approach that chelmertz suggests.) However, this means you need to know exactly how many viewers there are, and all viewers will need to respond before you can complete the deletion. Do you always have three viewers? Are there ever only two? What if there is an error in one of the viewers - Should the delete fail, or do you want to go ahead and delete the object anyway?

The nice thing about an event-driven system is that you don't normally have to worry about these sorts of questions: You just make your change to the model (in this case, delete the object) and fire a change event. You don't need to know anything about your viewers.

So, if this were my system, I would try to figure out a way to make model changes cancelable only before they are applied to the model, rather than trying to apply changes to other views through the model and then trying to roll back those changes later.

Joe Carnahan