1

I have browsed through many articles online trying to grok the essence of the Publisher-Subscriber pattern, but they often:

  • A) contain unnecessary/extra domain-specific components or information
  • B) are unreliable or inconsistent with serious OOP standards

I'm looking for the most basic, abstract explication of this pattern, not industry story problems or real world analogies. I simply want to know, in the abstract:

What are the bare minimum classes that must exist and what must their interfaces include, to embody the Publisher-Subscriber design pattern in OOP?

Presented with clear, minimal markdown code demonstrations. (Preferably in TypeScript or strictly-annotated Python)

From what I've gathered, it seems that the three main classes are

class Publisher {}
class Subscriber {}
class Broker {}

with potentially other OOP constructs such as Topic or Event etc. But I am not sure what methods/attributes each should have.

Michael Moreno
  • 947
  • 1
  • 7
  • 24

1 Answers1

1

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!");
StepUp
  • 36,391
  • 15
  • 88
  • 148
  • This is great, the only thing I'd want added is some code markdown for the Publisher-Subscriber pattern, since it's distinct from the Observer pattern. Or were you trying to say that, given that PubSub pattern is cross-application and network-oriented, it wouldn't make sense to view it as an association of OOP classes in a file like we can the observer pattern? – Michael Moreno Dec 22 '22 at 16:39
  • 2
    Note the GoF book explicitly states on page 293 that the Observer Pattern is synonymous with Publish-Subscribe. That hasn't prevented debate over perceived [differences](https://stackoverflow.com/q/15594905/1371329), but I don't know if there is any formal consensus or hard line drawn between these terms. – jaco0646 Dec 22 '22 at 18:32
  • @MichaelMoreno yeah, you are right that it would not make sense to show an auxiliary code that will subscribe to some queueing system like [Kafka](https://kafka.apache.org/) – StepUp Dec 22 '22 at 18:36
  • 1
    @jaco0646 I suppose new meaning of Publisher and subscriber come from popularity of message queue systems and maybe it is less convenient to call the whole system as observer. I am not sure it is just my guess) – StepUp Dec 22 '22 at 18:43