Observer pattern probably is one of the most often used design patterns originally recommended by "The Gang of Four". In many cases, the Observer model can work as a GUI notification mechanism, but it is less than ideal. Just like any other patterns, Observer has numerous limitations, particularly when it is used on GUI. Some important limitations are:
1) As with any interface-based design, your oberver model is an very intrusive and very public solution. Suppose you wanted to subscribe to many notifications, not one. This is typically what you do with GUI. A typical GUI generates a large number of events to which you might need to subscribe.
2) Another related problem is that use of an interface means that your Update() method must be public. Any code then can call it at any time.
3) That said, Observer has to be interface-based. Because if you don't use interface-based design, SubjectBase class would be tightly coupled to GUIObservser class. In other word, only GUIObserver instances can attach to a Subject. If some other class has a method that you want Notify() to call, you'll have to create a whole new SubjectBase-like class. So the problem is not in the interface; it is Observer model's limitation.
4) Observer model handles one-to-many subscription fairly well. By one-to-many, I mean that many observers subscribe to one subject. But when an event fires, the notifications to all the subscribed observers are linear, meaning that observers will get callback one by one following exactly the same order for every loop. There are variants that instead of direct callbacks, Subject puts a message on each observer's message queue. This way, they create a "random" notification mechanism.
5) Thread-safety issue. There usually is very tight coupling between Subject and Observers. when notifying, Subject has to call into Observers' update() one by one. If one call has not returned promptly, or caught some exception, next call cannot be made. To avoid this, some usually implements a multithreaded refresh mechanism on the Subject side. So now the thread-safety becomes an issue, as the observer's data has to be proteced while it's being updated.
6) .NET Delegate/Event model solves some of these problems and creates a safer, more robust, more encapsulated style of notification. Specifically, I think it solves the problems 1-3 cleanly. I'm not quite sure whether the event model is thread safe by itself, though.
On Windows, I think the original messaging model and now the new event model is an better option than primitive Observer model. I still use Observer patterns a lot, but not for replacing Windows event model. On non-Windows platforms, I do see numerous examples of using Observer pattern as a GUI notification mechanism (I guess, Unix/Linux platform does not have a built-in messaging framework like Windows). I am pretty sure that many developers out there use Observer pattern on many other areas as well.