
Stewart, Robert wrote:
Jeff Flinn wrote:
Stewart, Robert wrote:
Jeff Flinn wrote:
That said, in my experience singletons are generally used as a crutch to access global state. They do access global state, but there often is global state in an application. If Singletons provide the only means to access state, they formalize that access. Singletons can also, using policies, control lifetime, post-destruction behavior, etc. Consequently, Singletons are more than a crutch, though often overused, abused, or misused. Well, I've yet to come across a case where global state couldn't have been avoided by passing the appropriate objects by value or reference along the function call chain.
That is certainly possible. It is also possible to use return codes rather than exceptions for all error reporting, though that's hardly a good idea. Throwing exceptions and catching them in higher level code means the code in the middle is ignorant of the error state. Singletons work similarly. Code buried well down the call stack needs access to some state. Without a Singleton for that state, all functions up the call stack must be changed to pass along that state. Using Singletons eliminates that burden.
I fail to see the analogy between global-state-coupling and exceptions. In the former, you've got a function with dependency upon global state, and any function that calls that function is now dependent upon global state. The only way I can tell that dependency is I have to hunt that down by looking at the source code, or trying to link and getting an unresolved ref liner error. How are exceptions similar? What use cases do you see where global state access is required?
Doing so avoids the mess that ensues when trying to unit test classes and functions that use supposed singletons/global state.
I can't argue with that. It is also easier to unit test functions returning error codes, but that shouldn't be the only factor in design.
I can just as easily test that a function does or does not throw given a set of arguments as I can test that I get the proper return values. Most unit test libraries specifically provide exception support. Jeff