Publisher-subscriber is a network oriented architectural pattern and Observer is an object-event oriented pattern.
They both are used at different Software levels.
In other words, observer is implemented within the boundaries of an application or within a single process. Publish-Subscribe is a cross application communication pattern with messages being exchanged between different processes.
Generally, if we talk about Observer pattern, what we need is just two classes:
- Publisher or Subject. What you want to hear. Source of events
- Subscriber - or observer. Who wants to hear events generated by publisher or subject
So let me show an example. These are abstractions of Observer and Publisher(Subject)
interface IMyObserver
{
update: (myMessage: string) => void;
}
interface IMySubject
{
registerObserver: (o: IMyObserver) => void;
removeObserver: (o: IMyObserver) => void;
notifyObservers: () => void;
}
And this is a concrete implementation of IMyObserver
:
class MyObserver implements IMyObserver
{
_mySubject: MySubject
_myMessage: string | undefined
constructor(mySubject: MySubject)
{
this._mySubject = mySubject;
this._mySubject.registerObserver(this);
}
update(myMessage: string) : void {
this._myMessage = myMessage;
console.log(`Observer have seen this message: ${this._myMessage}`);
}
}
This is a concrete implementation of IMySubject
:
class MySubject implements IMySubject
{
_observers: IMyObserver[] = []
_myMessage?: string
_messageFromObserver?: string
notifyObservers()
{
this._observers.forEach(obs => obs.update(this._myMessage ?? ''))
}
registerObserver(o: IMyObserver):void {
this._observers.push(o)
}
removeObserver(o: IMyObserver) {
const index = this._observers.indexOf(o);
if(index !== -1) {
this._observers.splice(index, 1);
}
}
myMessageChanged() {
this.notifyObservers()
};
setMessage(message: string)
{
this._myMessage = message;
this.myMessageChanged();
}
}
And then you can run the above code like this:
const mySubject = new MySubject();
const myObserver = new MyObserver(mySubject);
// message from subject
mySubject.setMessage("Hello World!");