質問

There are several incarnations of Observer pattern: Listeners, Events etc. (am I right?)

But today we found we have no agreement among team members - is it possible that Listener (Observer) affect execution of the method which invokes it.

 

The example was proposed as following: when the deal is saved via DealDao, it could fire an event which would be caught by some Listener which will:

  • update calculated fields in the deal (some fees etc.);
  • create some dependent entities.

I myself greatly dislike this approach - for example because if update of dependent entity in the listener throws an exception, the deal update should be rolled back too.

But it seems unnatural that Listener forces the subject to roll back.

役に立ちましたか?

解決

In general if you are changing the behavior of the object then you may be implementing the Strategy Pattern not the Observer Pattern.

Modifying the model itself in response to observed events on it can lead to very complicated behavior so I wouldn't really recommend it but it is valid.

Generally try to think about the "flow" of data and operations through your system. If you can make the flow always go in one direction (or at least have as few loops as possible) then the whole thing becomes a lot more simple to manage and understand.

Adding an observer is "down flow" from the original data. If that observer then goes back and modifies the original data then that is flowing upstream and makes the behavior of your whole program a lot more complicated. For example what happens if that change then triggers another event, which then comes back into the same observer again, etc? Someone tracing through the execution is going to find unexpected data changes until they find that observer and you run into the potential for recursive loops that stack overflow and all sorts of similar fun and games.

他のヒント

If there are no listeners to DealDao, will the deal be saved at all?

If yes, then you actually have an implicit listener which actually does saving operation. Then, when another listener is added which updates fields in the deal, then we have two listeners which operate on the same object. This is clearly violation of encapsulation principle which may cause problems. But Observer Pattern is not in vain: similary, you could get same effect in other way. As user Tim B pointed, first design flow of data with minimum of loops, that is, as a graph with nodes and edges, and let each node be well-defined object (in OOP sense). Only after that, think how to implement it, and Observer Pattern is a valid option.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top