Boost logo

Boost :

From: Johan Nilsson (r.johan.nilsson_at_[hidden])
Date: 2008-01-18 03:15:09


Pierre-Jules Tremblay wrote:
> On Jan 17, 2008 2:15 AM, Johan Nilsson <r.johan.nilsson_at_[hidden]>
> wrote:
>>>> Did you notice that it is possible to use multiple inheritance?
>>>> This way you can implement and test your domain-specific logic as a
>>>> "normal" class, and then just expose a singleton of that specific
>>>> type using e.g. boost::singleton<>.
>>>
>>> Yes, it makes it possible to test the class to be wrapped as a
>>> singleton. That's the easy part. The hard part is to make the
>>> singleton's client code testable.
>>>
>>> If I have a singleton class A that wraps a "regular" class B, I can
>>> test B independently of A. However, I have no way to test any code
>>> that calls A::instance to get to B.
>>
>> That's why you should use dependency injection instead of designing
>> the client code to directly call A::instance(). Why does the client
>> code need to know it is accessing a singleton, when all it wants is
>> the domain-specific logic?
>
> I agree and advocate for dependency injection myself. But your
> original comment was that somehow Tobias' singleton's
> multiple-inheritance support makes it possible to test the code. I'm
> saying it only enables you to test the
> class-to-be-used-as-a-singleton's code, not the client code.

Exactly. I never said that MI somehow magically enables you to test the
client code. It can help, though.

> Now
> you're saying the client code shouldn't depend on the class being used
> as a singleton.

Yes. The client code should depend on the "class-to-be-used-as-a-singleton".
Example:

class Foo {};
class FooSingleton : public Foo, public singleton<FooSingleton, ...> {};

Unit-test Foo as normal and make clients depend on Foo rather than
FooSingleton. If you need to use e.g. "lease", design an adapter interface
or concept (depending on whether you want to use dynamic or static
polymorphism) that mirrors that behaviour and make clients depend on that
instead.

> I agree, but Tobias' design doesn't make that use
> case possible,

I wouldn't say that the particular use case is impossible, possibly awkward.
See above.

> so what are you suggesting (in the context of this
> particular review)?

This is getting off-topic I think, so I won't disturb the review by further
comments on testability.

I guess that what I'm saying is that code that uses singletons are testable,
even without the "settable singleton" variety, as long as one carefully
designs the client code not to directly access the singleton; i.e. don't
call singleton::instance().

Note that when using static polymorphism you could even allow clients to
directly call singleton::instance(), as long as singletons' type is a
template parameter for the client.

/ Johan


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