Observables Need To Be Consistent

Suppose I have an observer pattern in my code that deals with state. This means the following: I've got an object A, observed by objects B1, ..., BN and, depending on the state of A, B1, ..., BN do stuff. E.g. something like MVC.

What I don't want is operations on A that throw long-lived exceptions. Suppose I call

A.foo()

and it partially changes the state of A and then, before notifying the observers, wonks out with an exception that travels through 17 objects

(because I used Throw Dont Catch in my design).

All of a sudden, my views on the model are out of date. I need to deal with this. In advance if possible. The tentative conclusions are: Observe Simple Things and Change Complex Observables Using Transactions

Or perhaps simply Tidy Up Before Throwing


Leaving an object in an inconsistent state is a problem for any object, not just observers. Cf the Design By Contract approach advocated by Eiffel. Meyer says that a routine either fullfills its contract, in which case it returns normally, or else it fails, in which case it cleans up and throws an exception. It doesn't half-complete.

The cleanup is easiest if the exceptional condition can be detected before any changes are actually made, of course - this leads to exceptions being thrown only for what we might consider violations of the pre-condition. Immutable objects plus garbage collection also make cleanup easier. We can just drop the half-formed object on the floor.

Anyway, this doesn't mean Observables can't throw exceptions. It can throw them before it has made any (externally visible) state changes. Or, sometimes, a big change can be broken into atomic parts that stand or fall alone. Thus:

doPart1(); try { doPart2(); doPart3(); } finally { observers.notify(); // At least part 1 got done. }

(This is an example of Use Finally Clause.)



See original on c2.com