Over a million developers have joined DZone.

Alas, Solution Sans Singleton Ensued

DZone's Guide to

Alas, Solution Sans Singleton Ensued

· Performance Zone ·
Free Resource

Sensu is an open source monitoring event pipeline. Try it today.


Wow, I thought that post about singletons was going to bring out the Vampire Hunters to try to stake me. Like the time I said 2 or 3 years ago that there was a coming SQL collapse, but I guess those guys are stalking more important prey, or maybe the Singleton is one of those things where people feel an obligation to be against it, but then when they are behind closed doors, they know it‘s something they will be using themselves.

In the case I trotted out to argue that Singleton was the scapegoat of the first generation frustrated Bean-ifiers, I ended up instead implementing a Chain of Responsibility pattern. I know what you are thinking: how could those be in any way interchangeable, or functionally equivalent. Well, I was going to do a CoR for other reasons, the need to hold state was what made Singleton seem inevitable, but the introduction of a minor hinge made it unneeded: the idea that one participant in the chain might supply data that could be picked up by the other. So, to restate the problem: I was getting forecasts and found out I could get a whole day‘s worth, so I don‘t want to go back to the source an hour from now and do REST and scrape the result again, if I can just get the whole day and hang on to it.

The way the Chain of Responsibility implementation works is the first agent looks for the hourly forecast in the local db. If it‘s not there, it‘s done and invokes its successor on the chain. The second participant goes out to the service, and if it gets a whole day‘s forecast, it stores that in the local db, and returns the hourly (the requirement we are satisfying) and we are done. (A third and irrelevant chain is if there is no forecast for you, I can approximate one.)

The nice thing about this is that it has the additional benefit of conferring some amount of offline behavior to the application, as a side benefit: if the day‘s forecast was fetched in the morning, and an hour later, is needed, but there is no connection, we are in luck.

The thing that‘s a tad questionable here is our minds want to tell us that we have two collaborators that are depending on each other, and that‘s bad. But do we? I don‘t think so. Furthermore, Chain of Responsibility has a quality somewhat similar to Visitor in that it can take disparate processing and pull it under a single umbrella (e.g. a Visitor that provides printing for different types has the desirable side effect that if you want to see how anything is being transformed for output, you can go to one place). This is a key element of Agent or Actor-based programming: that on the one hand the Agent must be a standalone functor, but, of course, it has to plug into a scheme of cooperation.

Interestingly, this morning I was looking for a way to make a set of buttons appear at the top of the page in a PageViewController and found this thread on StackOverflow. What‘s kind of interesting about it is that the responder chain in Cocoa is an implementation of Chain of Responsibility and this thread has a lot of participation, and not one of them acknowledges the design, its intent, let alone advances a solution that leverages it. Instead, it‘s a contest for who has the most elegant solution for setting it aside. The most ludicrous part is we have examples that show this is not needed: if you go into iBooks and tap on the far right part of the page, it turns the page, if you tap near the top or bottom, the controls appear. This is the dark side of things like StackOverflow, and seeing programming as just a bunch of design-free obstacles that need to be cleared: more Mario Brothers than Gang of Four.

Sensu: workflow automation for monitoring. Learn more—download the whitepaper.


Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}