Home » PHP » PHP Tutorial: King Floyd and the Seventeen Princes - A Tale of the Observer Pattern

PHP Tutorial: King Floyd and the Seventeen Princes - A Tale of the Observer Pattern

Since I've been getting positive feedback on design patterns as stories, here's another:

Back before horses were invented, the tiny kingdom of Schadenfreude was ruled by good King Floyd and Queen Tillie, who were worried that their son Prince Roscoe would never find a wife. In the neighboring kingdom of Punim, King Marvin had a beautiful daughter named Shayna who was an excellent marriage prospect. She was clever, beautiful, and had massive tracts of land. Floyd and Tillie gathered up the royal retainers and ventured out to see King Marvin.

Schadenfreude and Punim were on good terms, although Schadenfreude's diplomats always seemed a little too happy when things went wrong in Punim. King Marvin agreed that the marriage between Roscoe of Schadenfreude and Shayna of Punim would be a good thing.

Now, though Punim was a mostly happy kingdom on its face, there was one source of unhappiness. Only a male of the royal blood could inherit the throne. Since King Marvin had no male children, there was great infighting among his seventeen brothers about who would take the throne when Marvin died. As soon as they were married, it fell upon Roscoe and Shayna to have a son as soon as they could, so that there would be an heir to King Marvin's throne and end the fighting.

The fates smiled upon the couple and Shayna was soon pregnant, but though they visited wizard after wizard, none could say for sure whether Shayna would have a boy or a girl. Shayna was 7 months along when her father, King Marvin, fell gravely ill. His doctors gave him three months to live and his brothers began jockeying for power. But none could make a move until it was known if Princess Shayna and Prince Roscoe's child was a boy or a girl.

Every prince sent an ambassador to the court of King Floyd. Each ambassador had the same request "send your swiftest messenger on your strongest horse to tell my master if the child is a girl. You will be richly rewarded." Since horses had not yet been invented, Floyd found this request puzzling, yet every ambassador made it and Floyd was left in an uncomfortable situation. If he favored one brother over another, that brother might become king and reward him, but that brother might also fail, and that could leave Floyd on bad terms with the brother who succeeded.

Schadenfreude could not afford a spy corps that could return enough information for Floyd to judge which brother he should ally with, so he called for Alan, the royal wizard. Alan listened intently to King Floyd's dilemma and proposed a solution. "I will create a special magic mirror for this birth()." Alan called it "birth()" because the parentheses to him looked like the opening through which the baby would come.

"Every wizard whose master is interested in knowing the results of the birth() can use their magic communication objects to register their intent with the magic mirror. This way we do not have to construct the mirror with foreknowledge of all the other magic objects it must notify. When birth() happens, the mirror will merely run through the list of objects that have registered with it and transmit the event to them. This will happen so quickly, no one prince will be able to claim we showed favor to another."

King Floyd thought this a marvelous solution and commissioned the wizard Alan to build such a mirror. He completed it quickly, using methods he had previously developed to speed its construction. The ambassadors were all sent back to their princes with instructions on how to register with the magic mirror. And when the baby was born, the magic mirror sent "child = boy" to all the registered objects.

Because he made so many brothers unhappy, they named him Joseph. And when he grew up, he invented horses.

The End

The first place I recall encountering the observer pattern was not in PHP, but in JavaScript. If you've ever set a listener to fire when an event happened, you've used the observer pattern. Functions or methods are registered with an object so that when it experiences a specific event, it "notifies" the registered functions or methods by calling them.

This is a great example of loose coupling. The object that implements the "subject" part of the observer pattern has no foreknowledge of the other classes/objects that will observe it, so they're not hardcoded into the class. Instead, they're registered or attached as needed at runtime. Going back to JavaScript and HTML, I can create this button:

<button id="button1" type="button" value="My Button" onClick="myFunction();"/>

That's a tightly coupled button that DOESN'T implement the observer pattern, because the function the button will call is hardcoded into the button's HTML. On the other hand, I can register a listener for the button's click event very easily with jQuery.

<script type="text/javascript">
	$("#button1").click(function(){
		// some code goes here
	});
</script>
<button id="button1" type="button" value="My Button"/>

Though it's a little more typing to set the listener instead of an onClick handler in the button's instantiation, you can set multiple listeners that will all fire on the click without changing the HTML.

I'm sorry I didn't give sample code for an observer pattern in PHP, but web user interfaces are so observer oriented, it just felt like I had to go with the JS example. Plus, I don't know about you, but I don't have the option of being a "pure" PHP coder. I have to work with JavaScript and jQuery periodically, so mixing things up doesn't hurt as far as I'm concerned.

If you really want a PHP implementation, check out the documentation for the SplSubject interface. The SPL (Standard PHP Library) bakes in some language level support for the observer pattern with the SplSubject and SplObserver interfaces.

2 Responses to PHP Tutorial: King Floyd and the Seventeen Princes - A Tale of the Observer Pattern

  1. What happened to Marvin?

    • Sadly, the three months to live prediction came true. He passed away shortly after Joseph was born. But Prince Roscoe ruled Punim on Joseph's behalf until he reached manhood and took over the throne. Eventually, Joseph united the kingdoms of Punim and Schadenfreude under one flag and began a golden age that lasted centuries.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>