Quickly going through the GoF and the Head First Design Patterns book, it seems like there is no mentioning of infinite loop detection and handling for the Observer pattern?
I think if it is between 2 classes, we can be more careful about the infinite loop problem, but what if there are 5 classes or 12 classes, and the observers go multi-directions. In this case, won't an infinite loop be possible and some detection should be added to this pattern?
Infinite loop handling could be part of the actual implementation of the pattern, but the description of the pattern itself should be general and not be concerned with these details.
It is kinda weird that people with high rating give such a useless answers. sigh
Event loops happen and happen VERY often in GUI programming. It seems to me that more or less standard solution is to break the loops by either filtering duplicate or redundant events or introduce some method that do not trigger events.
As @Matthew points out this would be a case of poor design and you ought to catch that during design and solve it by improving the design, not adding more complexity to the code. Specifically, I think it would be a sign that classes lack cohesion, that responsibilities are spread out through the various classes rather than properly assigned to a single class or small set of cooperating classes. Properly applied to a good architectural design the Observer pattern ought not need any special handling to prevent the infinite generation of callbacks.
Infinite loops can only happen if (a) Observers are also Observable, (b) changes they observe can lead to changes in themselves, (c) the graph of observation is cyclic and (d) there is a kind of change which can end up triggering a change of the same kind. The ideal solution would be to design out the risk of infinite loops by ensuring one of those requirements is absent. If your current design makes all four true, see if you can change it to make one of them false.
The traditional uses for Observer-Observable are in layered architectures - for instance, where view-controllers observe model objects, or where event handlers observe GUI components - and here, the graph will not be cyclic, so there's no risk of infinite loop.
I should probably explain about point (d), about different kinds of changes. What i mean is that if you have a situation where, say, a UserInputEvent can trigger a ModelStateChangedEvent, and a ModelStateChangedEvent can trigger a WidgetUpdateEvent, which can't itself trigger anything, then even if the Observers form a cyclic graph, you can never get infinite loops, because there's only a finite number of stages in the sequence of events. Effectively, the events form an acyclic graph, even if the Observers don't. If, however, a ModelStateChangedEvent can trigger another ModelStateChangedEvent, then you have the risk of cycles.
If you really can't avoid the risk of cycles, then you can steal an idea from Jon Postel, and make every event notification carry an integer time-to-live counter. When an Observable broadcasts an 'original' event, meaning something that comes in from outside the network of Observers and kicks off a cascade of events inside it, it sets the counter to some suitable initial TTL value. When an Observable responds to an event by broadcasting another event, it would use a TTL one less than that of the triggering event. When an Observer gets a notification with a TTL of zero, it ignores it. This would prevent infinite loops, but would also prevent an Observer responding 'correctly' to some events, so it's an idea to be used with caution. I would strongly suggest that an event cascade hitting the TTL limit should be considered the result of a programming error, and should be logged and reported in the same way as you'd handle something like a NullPointerException or an assertion failure.
No. Any situation causing an infinite loop is obviously a sign of a bad design. I have never seen this happen by accident in the observer, and I don't see a need to write special cases for it in the observables.
This is a case of Don't Do That Then.
Is in general the infinite loop check equivalent to the Turing's halting problem? If so then could not be possible.