Q: It seems to me that the Observer design pattern as described in GOF is really the same thing as listeners found in various toolkits. Is there a difference between the concepts, or are listeners and observers really the same thing. I'm looking for a design answer, not a language-specific answer.
Observer Design Pattern vs "Listeners"?
The GOF Observer pattern is an object-oriented, closed-communication system. That means you have to have at least one class instance built explicitly as an observer that can accept the registration of other objects built with some "observable" interface. Then, when those observed objects change state, the observer is informed and can do something about it. The requirement is the construction of, and use of registration between well fitting classes. Then communication occurs only between observer and observed in a highly controlled system.
Event paradigms, however, have neither the requirement of registration nor of object-oriented design. Any object or function can emit an event, even a custom one. By "emit" I mean broadcast: it doesn't care who is out there "listening" for the event and doesn't expect a response. This allows for much more free-form design and extremely loose coupling at the cost of rigid communication control. It's also easier to extend event-driven applications because the pieces don't have to "fit" together as snugly as in the Observer pattern (no registration) and you're not tied to implementing an "observable" interface (no OO requirement). You can just create another listener function that handles an event when it hears it.
Some applications, especially lower-level OS ones, benefit highly from the control gained by using the observer pattern. Other applications, particularly Internet-based applications, tend to benefit from an event-driven design.