
Cliff Green wrote:
Jeff Garland <jeff@crystalclearsoftware.com> wrote:
My only big design regret from my last project was using Singletons in an infrastructure library layer used by multiple applications. I will never do it again. Promise!
My design policy now is to never embed Singletons in a library - if an application wants to instantiate a library object as a Singleton, let the app take responsibility and manage it accordingly (of course a good generic Singleton library in Boost would help ease some of the not-trivial issues with Singletons).
I agree with the design philosophy...it's really pretty rare that the singleton is absolutely required. Oh, and btw, the standard library has been burned by this too -- the instantiation weight of std::cout, std::err, etc make the inclusion of the iostream header a killer for embedded apps (several K size increase in the executable just by including)... There has been a boost.singleton proposed and I believe rejected and probably given up on by now.
Here's an example from ACE, that caused untold wasted hours in problem analysis: ACE Reactors have a Singleton interface, allowing simple and easy Reactor instantiation and use. Two different application layers (written by different teams) were using the ACE Reactor Singleton in the same application. Depending on what event handlers were registered with the Reactor and which events were processed, unexpected results occurred. Unit tests were absolutely clean, since the unit tests only tested the event handlers from one layer. If the separate layers had each instantiated their own Reactor objects, interference would not have happened.
And don't get me started on the initialization, dynamic library loading, and multi-threaded issues I've had to work through with Singletons ...
Ok -- here's another fun one: destruction order of co-dependent singletons crashing the process on exit -- that's always a fun one to fix ;-) Jeff