Re: StateFull vs Stateless Singleton
On 5 juuli, 05:48, sebastian <sebastianga...@gmail.com> wrote:
On Jul 4, 6:31 pm, =D6=F6 Tiib <oot...@hot.ee> wrote:
On 4 juuli, 23:58, sebastian <sebastianga...@gmail.com> wrote:
On Jul 4, 9:02 am, Pallav singh <singh.pal...@gmail.com> wrote:
Hi
what the consideration parameter to choose stateless and statefull
Singleton ?
Thanks
Pallav Singh
Neither - a simple template class eliminates the issue altogether:
<code>
#include <stdexcept>
template < typename Type >
class singleton
{
public:
singleton( void )
{
Type* ptr = static_cast< Type* >( t=
his );
if( self )
{
/*
Or what have you...
*/
throw std::runtime_er=
ror
r: attempt to instantiate multiple instances of a singleton"
);
}
self = ptr;
}
static inline Type& instance( void )
{
return *self;
}
static inline bool exists( void )
{
return self != 0;
}
virtual ~singleton( void )
{
self = 0;
}
private:
singleton( singleton const& );
singleton& operator = ( singleton const& );
static Type* self;
};
template < typename Type >
Type* singleton< Type >::self = 0;
// Example:
#include <iostream>
class foo : public singleton< foo >
{
public:
void bar( void ) const
{
std::cout << "foo::bar( )" << std::en=
dl;
}
};
int main( void )
{
try
{
foo a;
foo::instance( ).bar( );
foo c; // Whoops!
foo::instance( ).bar( );
}
catch( std::exception const& error )
{
std::cerr << error.what( ) << std::en=
dl;
}
}
</code>
The beauty of the design is that it allows the user to decide how to
allocate and initialize the derived class; it's sole purpose is to
make sure that multiple instances aren't created. Best of all, it's
completely generic!
Cheers.
Looks as beautiful like any other reinvented square wheel. The
requirements seem to be that such code must work:
int main( void )
{
{
foo a;
foo::instance( ).bar( );
}
foo c; // Second singleton and *NO* Whoops
foo::instance( ).bar( );
}
Not sure why someone needs to have global state? Typical example of
singletons is a logger. Huh? So ... OK. What if i need to have
separate logs from different modules? I will then need new class for
each log to have separate singleton logger for each module? Nonsense.
What if i need to have separate logs from different threads? Then that
Logger::instance() should give me "different" singletons based on
thread ID? Huh? Why it can't just be debugging::log() and where it
logs is its internal business, no global state no nothing?
As for your code ... same thing with 10-12 lines instead of 70-80:
#include <iostream>
namespace foo
{
void bar()
{
std::cout << "foo::bar()" << std::endl;
}
}
int main()
{
foo::bar();
}
Things that contain nothing are not worth allocating or initializing.
So...your point is that you hate the singleton pattern? Got it. I hate
it when people post snarky comments for no apparent reason,
personally. To each his (and her) own, I guess.
Did i really insult you somewhere? Sorry then. I thought i posted
reasons. I do not dislike something blindly. I have met them more than
anyone deserves, and i have learned all possible and impossible ways
how to deal with them. One-size-fits-all solutions are usually wrong
so don't be insulted if yours is not exception.
Why the problem with singletons is not so apparent? What is the
difference between calling "globalVariable.doSomething()" and
"SingletonClass::instance().doSomething()" (other than some extra
letters to type on second case)? Both are tight coupling with global
state only semantics are different. Sometimes it is not worth to avoid
tight coupling between close classes but singleton is far and global.
The problem is not only tight coupling between distant things but that
such coupling is hidden within code (call site).
One often named purpose of singletons is that these limit the count of
how many instances there may be simultaneously (1 on case of
singleton). That sounds like responsibility of owners of objects to
limit number of simultaneous instances. Oh yes, global state does not
have owners, it is self-owned.
Also why only one instance? Who knows. "Pragmatic" reasons like "There
was only one window/database/display/player/client/user/account/store/
harddrive/configuration when we started with that application, so we
decided to carve it into rock in most hard way to modify." Mono-media.
Finally massive dependency on global state makes it impossible to rely
on unit tests. I can not imagine large project without even larger
amount of unit tests. Global state carries on behind scenes and so
unit tests may pass (or fail) just because of order in what these were
ran.
These are not apparent reasons? Imagine 25 man-years that was put into
C++ project. Result was with half of classes singletons (with
similarly various "solutions" and "purposes" and "pragmatic reasons").
Someone was paying lot of money for these 25 man-years so it was
like ... desirable thing for him. Original global-state-lover
architects did run far away because quite non-ambitious and reasonable
change requests are near-impossible to fulfill. How to explain why
what he has now is so costly to extend or maintain?
So ... nothing personal, sebastian, but yes i dislike singletons. For
good reasons.