Boost logo

Boost :

From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2008-01-16 10:27:15


Giovanni Piero Deretta wrote:
> Disclaimer: I'm just discussing the singleton patern per se.
> I haven't read the documentation of Boost.Singleton nor I can comment
> on its design.
> I'm not voting for nor aganist the library.

Yep, I'm aware of it. That's why I have kept the discussion free of all
the special features provided by the library.

>
> On Jan 16, 2008 12:05 PM, Tobias Schwinger <tschwinger_at_[hidden]> wrote:
>> Giovanni Piero Deretta wrote:
>>> On Jan 16, 2008 9:07 AM, Tobias Schwinger <tschwinger_at_[hidden]> wrote:
>>>> Giovanni Piero Deretta wrote:
>>>>> [...]
>>>>> I consider singletons just another form of globals and thus bad style.
>>>> Let's see:
>>>>
>>>> "I consider if, else, for, do, while and the ternary operator just
>>>> another form of goto and therefore bad style."
>>>>
>>> Except that 'if', 'else' and friends are a *restricted* form of goto
>>> (i.e. the 'structured' in structured programming) and are thus
>>> acceptable.
>> Let's see:
>>
>> "Singletons are 'structured' globals (i.e. the 'structure' in 'data
>> structure') and are thus acceptable."
>>
>
> Hum, the difference between "structured programming" and goto-based
> programming is well known and I didn't feel the need to define it.
> (but if you really want to:
> http://en.wikipedia.org/wiki/Structured_programming)

So should the difference between structured and unstructured data...

Thanks, I do know what "structured programming" is (and I'm even a fan
of it, avoiding too many 'return' statements and so). I was just playing
with words:

Just like a Singleton boils down to a global somewhere - structured flow
constrol statements boil down to 'goto's. There are many good reasons to
avoid global variables and Singletons address quite a few of them.

>
> What is not obvious (to me at least) is how singletons are more
> structured (in the sense of 'data structure') than a global object.
>

Global objects are often not an alternative because they don't work (we
can't assume constructors to be run in a portable, dynamic library).

>> Some more fun:
>>
>> "I/O registers are global and thus bad style, so I built a computer
>> without. Still trying to telepathically use that thing, though."
>>
>
> How *hardware* I/O registers have anything to do with software
> engineering best practices?

I'm not talking about the register's hardware. I'm talking about their
representation in *software* ;-).

My point is: Systems have globals.

>
>>> In general, a singleton hardly adds any restriction to
>>> global (except from being thread safe). :)
>> Thread-safety is just a bonbon here: So let's take another look at the
>> key responsibilities of a Singleton is for:
>>
>> 1. Making the user implement a class
>> 1.1. encourages a well-defined object interface,
>> 1.2. embraces a design that can easily be changed to use non-globally
>> scoped objects instead, and
>> 1.3. prevents pollution of the global namespace.
>>
>> 2. Providing on-demand initialization
>> 2.1. makes non-trivial construction work with any ABI's shared libs, and
>> 2.2. automatically resolves dependencies between Singletons.
>>
>> 3. Ensuring a single instance of the Singleton class
>> 3.1. allows to properly model unique facilities (hardware, registries,
>> etc.) in an object oriented fashion, and
>> 3.2. allows to encapsulate a well-defined access point in the first
>> place.
>> [...]
>
> The problem is that most of these points just make globals more
> usable, do not really address the problem with globals: an implicitly
> shared resource.

There are resources that *are* global and thus shared. There is nothing
wrong with that!

The question arises how to best model them.

> In particular:
>
>> 1.2. embraces a design that can easily be changed to use non-globally
>> scoped objects instead, and
>
> How? Or you design upfront not to rely on a non global scoped object,
> passing around a state pointer and not assuming global visibility of
> changes or you don't.

We have the choice to use parameters instead of obtaining the Singleton
instance globally for a subsystem and thus to simplify reuse.

>
>> 3.1. allows to properly model unique facilities (hardware, registries,
>> etc.) in an object oriented fashion, and
>
> I do not think you can usefully provide an OO interface to hardware
> registers, and anyways what is unique in one release of your hardware
> might not be in the next one.

I don't think this discussion is coupled to a particular abstraction
level. Registers become devices and devices become connections.

Then there are registry services (extended type info to provide some
framework-specific form of reflection, for instance), loggers, etc.

> There might be higher level abstractions that are best modelled as
> singletons. The point is, are these common enough that they deserve a
> generic solution?

Yes, I think so.

Especially because there are many subtle pitfalls in this area.

Regards,
Tobias


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk