Request for Feedback on the Singularity Design Pattern

The Singularity Design Pattern seeks to address the three weaknesses of the Singleton Design Pattern. Namely: 1) Lifetime: Singleton introduces lifetime management complexities (for a detailed discussion, see Chapter 6 of Modern C++ Design by Andrei * Alexandrescu*). 2) Initialization: Singleton restricts the class to the default constructor. This makes Singleton unusable for classes which require non-default constructors. 3) Encapsulation: Singleton provides global access to the class. Some may view this as a feature, but advocates of unit testing, dependency injection, and context independent objects would disagree. Singularity guarantees a single instance of a class, but does not suffer from 1-3 above. Usage is as follows: // Usage as a Factory: typedef singularity<Horizon, single_threaded> HorizonSingularityType; Horizon & horizonF = HorizonSingularityType::create(value, &event, event); HorizonSingularityType::destroy(); // Usage as a Base Class: class Horizon : public singularity<Horizon, multi_threaded, global_access> Horizon & horizonB = Horizon::create(value, &event, event); Horizon & horizonC = Horizon::get(); Horizon::destroy(); The usage example above shows the three advantages of Singularity over Singleton: 1) Singularity does not permit lazy initialization by design. The lifetime of the single object is bounded by create() and destroy(), and this lifetime is managed just like objects bounded by new() and delete(). 2) Singularities of objects can be created using any available constructor for that object. 3) Singularity prevents global access to the instance by default. However, if this is required, or will help to transition from Singleton, a policy can be supplied which enables a get() accessor to the instance. It is also worth pointing out that thread safety is policy based, and both a single_threaded, and multi_threaded policy are provided. The source files are available here: http://www.mediafire.com/?d8kn5fx2n5d22 I look forward to your feedback. Thank you, Ben Robinson, Ph.D.

Hi, I didn't look at the code yet but maybe it would be another good opportunity to test one of those code review tools? I don't know who manage this. About the interest, I've been using a not-as-generic-and-not-thread-safe solution that looks like your's but was still calling it a Singleton because of the lack of other word (and it does generate a lot of confusion in discussions on Singletons). So I'm interested to have this Singularity in boost. Doesn't Singularity means a lot more than the current context? I know the word only from hard science fiction and science related articles; and I'm not native english so maybe I don't know simpler meaning than in those contexts. Joël Lamotte PS : I just tried to get the source code and it seems my company firewall forbids the website. Can you expose it in github.com, bitbucket.com or code.google.com, or at least send it to me by mail, please? I'm sorry for the trouble, in last resort I'll get it once home this night.

2011/6/27 Klaim - Joël Lamotte <mjklaim@gmail.com>
Hi, ... About the interest, I've been using a not-as-generic-and-not-thread-safe solution that looks like your's but was still calling it a Singleton because of the lack of other word (and it does generate a lot of confusion in discussions on Singletons). So I'm interested to have this Singularity in boost.
So am I. :) Doesn't Singularity means a lot more than the current context? I know the
word only from hard science fiction and science related articles; and I'm not native english so maybe I don't know simpler meaning than in those contexts.
From the Free Merriam-Webster Online Dictionary: Definition of SINGULARITY 1 : something that is singular: as a : a separate unit
I did name my sample object Horizon, which take an Event argument, as a double entendre. Also, there is always only one horizon, no matter which celestial body you are on. Joël Lamotte
PS : I just tried to get the source code and it seems my company firewall forbids the website. Can you expose it in github.com, bitbucket.com or code.google.com, or at least send it to me by mail, please? I'm sorry for the trouble, in last resort I'll get it once home this night. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
The source is now available on GitHub at: https://github.com/icaretaker/Singularity Thank you, Ben Robinson, Ph.D.

On Tue, Jun 28, 2011 at 07:13, Ben Robinson <icaretaker@gmail.com> wrote:
The source is now available on GitHub at:
I started to read it and I have a minor suggestion : would it be a good idea to also allow creation/destruction of the object without using create() and destroy()? class TheObject : public singularity<TheObject, global_access > {...} m_the_object = new TheObject(); ... // in another module auto& the_object = TheObject::get(); // ok if run after the previous code ... // in another function delete m_the_object; // now TheObject::get() will throw I've seen such possibility in Singleton implementations and found it useful but I'm not sure if it's a good idea because of the destruction function throwing. Joël Lamotte

2011/6/28 Klaim - Joël Lamotte <mjklaim@gmail.com>
On Tue, Jun 28, 2011 at 07:13, Ben Robinson <icaretaker@gmail.com> wrote:
The source is now available on GitHub at:
I started to read it and I have a minor suggestion : would it be a good idea to also allow creation/destruction of the object without using create() and destroy()?
class TheObject : public singularity<TheObject, global_access > {...}
m_the_object = new TheObject(); ...
// in another module auto& the_object = TheObject::get(); // ok if run after the previous code ...
// in another function delete m_the_object; // now TheObject::get() will throw
I've seen such possibility in Singleton implementations and found it useful but I'm not sure if it's a good idea because of the destruction function throwing.
Thank you for your input. I explored your idea and created such a base class. However, I think that trying to combine using new() and delete() to manage the lifetime of an object, and then have the base class provide a static function which returns a reference to the singular instance of the class gets a little messy (subjective opinion).
However, to your point, any class can be made singular by simply adding a private static boolean to their class and properly detecting if an instance already exists inside the constructor. If global access is needed, a global pointer to this instance can be created, for example. I would like to define the Singularity Design Pattern as one in which the user calls T::create() and T::destroy() to explicitly manage the lifetime of the object. It is these explicit calls that makes lifetime management so much simpler with Singularity compared to Singleton. Singleton instead provides T::instance() to get the lazily initialized object, and the lazy initialization, and lack of control with destruction makes lifetime management a headache. Also, because T::get() is disabled by default for Singularity, no global access to the instance is required, as it is for Singleton. This is an additional benefit for those who would prefer to explicitly pass the object to those other object which need access to it. Thank you, Ben Robinson, Ph.D. Joël Lamotte
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On Mon, Jun 27, 2011 at 2:17 AM, Ben Robinson <icaretaker@gmail.com> wrote:
The Singularity Design Pattern...
The source files are available here:
http://www.mediafire.com/?d8kn5fx2n5d22
I look forward to your feedback.
Thank you,
Ben Robinson, Ph.D.
When does the constructor template <class T> ::boost::scoped_ptr<T> singularity_instance<T>::ptr(0); 'happen'? ie there can be problems with the construction order of globals. Tony

On Tue, Jun 28, 2011 at 8:13 PM, Gottlob Frege <gottlobfrege@gmail.com>wrote:
On Mon, Jun 27, 2011 at 2:17 AM, Ben Robinson <icaretaker@gmail.com> wrote:
The Singularity Design Pattern...
The source files are available here:
http://www.mediafire.com/?d8kn5fx2n5d22
I look forward to your feedback.
Thank you,
Ben Robinson, Ph.D.
When does the constructor template <class T> ::boost::scoped_ptr<T> singularity_instance<T>::ptr(0); 'happen'?
ie there can be problems with the construction order of globals.
The private pointer is statically initialized, but is initialized to zero. Only when the user calls singularity<T>::create(), is the pointer reset to hold the newly created object. Therefore, there should be no issues with the construction order of globals... Unless, you decide to put that ::create() call in the constructor of another, non-singularity global. I would argue however, that the problem there is not with the singularity itself, but the fact that it was contained and initialized inside a global. Singularity can't forbid you from doing that, and if you do so, you give up control of the lifetime of the singularized object. The recommended usage is to call create() eagerly after main, and store the reference, and pass it to whomever needs it. I appreciate your inquiry, Ben Robinson, Ph.D.
Tony _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (3)
-
Ben Robinson
-
Gottlob Frege
-
Klaim - Joël Lamotte