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, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk