Phabstractic: Observer/Publisher Design Pattern

asherwunk/phabstractic now supports the Observer and Publisher design patterns.

Observer/Publisher Design Pattern

Observer and Publisher software design patterns are useful, and are used in tandem to implement such things as event oriented programming.  These are actually two design patterns that work can work together, and because of that only one side is usually documented, that being the observer pattern.  I consider them two different patterns, because you do two different things (observer or publish).  Here is quote from Wikipedia on the observer design pattern:

The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.

Because I consider them two different things, I implemented them as two different patterns in phabstractic.  This gave rise to the fact that both an observer and a publisher registers the connections between objects.  I will explain this further when I write about the interaction between the two patterns.  First let’s examine the Observer pattern s implemented in PHP with Phabstractic.

Observer Design Pattern

When I think of an observer, I think of an object that has a need to be notified of something.  When I think about this notification I rely on the idea of finite-state machines, which are an entirely different subject, but the idea is that different states are entered at any one time.  Any ‘event’, such as a mouse-click or a list insertion can be identified as something changing the state that it’s in.  So, any time an observer is notified of something, that ‘state’ is portrayed as a message.

In order to separate or discern something as a message in particular, I decided I would make any piece of data distinguishable as indicating ‘state’.  In this line of thought, I developed an interface to define something that contained ‘state’, so that any object can implement this interface and act as a indicator of state (view on github):

This is all well and good.  I wanted to make sure any object could be a identified as an observer, so I first outlined what my observer would do in an interface file (view on github):

The idea here is that an observer will register ‘publishers’, or objects that are granted the ability to notify the observer object, which will, upon state change, call the observers’ notifyObserver()  method.  The maintaining of a list of publishers is optional, as any object can notify the observer simply by executing a call to the public notifyObserver()  method.  However, I decided that if I was implementing the observer as separate from the publisher I would make sure we would provide a method or way that we could see who or what the observer object is listening to.

Here, I implement the observer pattern as a PHP trait.  Because PHP is a single-inheritance language, that is a class can inherit from only one other class, it wouldn’t make a lot of sense to make observer functionality as a parent class.  Any object could be an observer, so the parent relationship of an object/class may already be taken up.  Introducing the observer pattern as another step in the inheritance chain isn’t feasible when disparate pieces of code can be observers.  Here is the trait (view on github):

As you can see, I couple this implementation of the observer design pattern with my implementation of the publisher design pattern.  We’ll cover the publisher design pattern below.

The default behavior of notifyObserver()  is to call a method on the observing object prefixed with ‘published’.  So if I passed a state object with the data ‘done’ to the default notifyObserver() it would search and call the method named ‘publishedYellow()’ on its host object.

Publisher Design Pattern

A publisher is an object that maintains a list of observer objects whom it notifies when there is a ‘state change’.  Much like the observer, I wanted to be able to distinguish objects as being publishers, and a good way of doing that is type-ducking, or using interfaces (view on github):

Here you can see the methods for attaching and detaching observers to the object.  You’ll also see methods for manipulating and storing a ‘state’ object as outlined above in the StateInterface.

I also implemented the publisher design pattern as a trait for the same reasons I did the observer design pattern.  I want any object, regardless of its position in an inheritance hierarchy to be able to be an observer or a publisher (view on github):

In the previous implementation, the maintained list of objects wasn’t necessary to the operation of the object.  Any outside object or function could call the observer’s notifyObserver() method to notify the observer of any state change anywhere.  This is not the case for a publisher.  When the publisher object’s state changes, it cycles through the maintained list of observers and then calls that observer’s notify method.

Working Together

The nice thing about implementing the observer and publisher independently, but also together is that we can determine how they work together.  By insisting that interfaces are followed before connecting and disconnecting from each other we can maintain the list of objects in both the observer and the publisher at once.

You’ll note how in attachObserver() we and attachPublisher() we do the same bit of logic:

So when we attach a publisher to an observer, it automatically keeps track of it in its own records, and when we attach an observer to a publisher it automatically keeps track of it in its own records.

You’ll notice the list of maintained objects is a Restricted Set.  I covered phabstractic’s implementation of Restricted Sets in a previous post.

Conclusion

Observers and Publisher design patterns are very important in that they enable a certain amount of reactive programming.  When you only want something to execute or occur when a particular event occurs it makes more sense to just test for state change then to hard code in an if clause for every step.  This way you can structure the execution pathway in an object oriented fashion.  This allows for more agent-oriented programming, as well as opens doors to such methods as parallel processing or graphical user interface programming.

This is part of the Phabstractic Library.

If you appreciate my programming please help support me through my Patreon.

photo credit: Color Me Rad 2016 via photopin (license)

Liked it? Take a second to support kadar on Patreon!

kadar

I'm just a wunk, trying to enjoy life. I am a cofounder of http//originalpursuitssoc.com/ and I like computers, code, creativity, and friends.

You may also like...

Leave a Reply

%d bloggers like this: