Thread overview | |||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
February 02, 2019 Singleton in Action? | ||||
---|---|---|---|---|
| ||||
Hi guys, I ran into another snag this morning while trying to implement a singleton. I found all kinds of examples of singleton definitions, but nothing about how to put them into practice. Can someone show me a code example for how one would actually use a singleton pattern in D? When I did the same thing in PHP, it took me forever to wrap my brain around it, so I'm hoping to get there a little faster this time. Here's the singleton code I've been playing with: class DSingleton { private: // Cache instantiation flag in thread-local bool // Thread local static bool instantiated_; // Thread global __gshared DSingleton instance_; this() { } // this() public: static DSingleton get() { if(!instantiated_) { synchronized(DSingleton.classinfo) { if(!instance_) { instance_ = new DSingleton(); writeln("creating"); } instantiated_ = true; } } else { writeln("not created"); } return(instance_); } // DSingleton() } // class DSingleton So, my big question is, do I instantiate like this: DSingleton singleton = new DSingleton; Or like this: DSingleton singleton = singleton.get(); And subsequent calls would be...? The same? Using get() only? |
February 02, 2019 Re: Singleton in Action? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ron Tarrant Attachments:
| On Sat, 2019-02-02 at 16:56 +0000, Ron Tarrant via Digitalmars-d-learn wrote: > Hi guys, and gals. > I ran into another snag this morning while trying to implement a singleton. I found all kinds of examples of singleton definitions, but nothing about how to put them into practice. General, these days, as far as I know, Singleton is considered one of the ultimate anti-patterns of software development. There are many positive reasons for this very negative view of Singleton especially if there is any hint of concurrency or parallelism involved. Also Singletons tend to deny sensible testing. > Can someone show me a code example for how one would actually use a singleton pattern in D? When I did the same thing in PHP, it took me forever to wrap my brain around it, so I'm hoping to get there a little faster this time. I'd suggest just not going here. Let's not have Singleton in D code. Alternatives include "Parameterize From Above" which I believe Kevlin Henney pushes strongly, and indeed he may be the source of the "pattern". (I believe it is a design not a pattern using the proper definition of pattern.) If the resource really is "singleton" then creating an actor or agent is now the usual solution in languages such as D, Rust, Go, even C++. > […] > So, my big question is, do I instantiate like this: > > DSingleton singleton = new DSingleton; This seems wrong. > Or like this: > > DSingleton singleton = singleton.get(); getting seems like the one true way, if you really have to do this. Can I indent that Singleton not be part of the canon of D programming. > And subsequent calls would be...? The same? Using get() only? > > -- Russel. =========================================== Dr Russel Winder t: +44 20 7585 2200 41 Buckmaster Road m: +44 7770 465 077 London SW11 1EN, UK w: www.russel.org.uk |
February 02, 2019 Re: Singleton in Action? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ron Tarrant | On Saturday, 2 February 2019 at 16:56:45 UTC, Ron Tarrant wrote:
> Hi guys,
>
> I ran into another snag this morning while trying to implement a singleton. I found all kinds of examples of singleton definitions, but nothing about how to put them into practice.
>
> Can someone show me a code example for how one would actually use a singleton pattern in D? When I did the same thing in PHP, it took me forever to wrap my brain around it, so I'm hoping to get there a little faster this time.
>
> Here's the singleton code I've been playing with:
>
> class DSingleton
> {
> private:
> // Cache instantiation flag in thread-local bool
> // Thread local
> static bool instantiated_;
>
> // Thread global
> __gshared DSingleton instance_;
>
> this()
> {
>
> } // this()
>
> public:
>
> static DSingleton get()
> {
> if(!instantiated_)
> {
> synchronized(DSingleton.classinfo)
> {
> if(!instance_)
> {
> instance_ = new DSingleton();
> writeln("creating");
> }
>
> instantiated_ = true;
> }
> }
> else
> {
> writeln("not created");
> }
>
> return(instance_);
>
> } // DSingleton()
>
> } // class DSingleton
>
> So, my big question is, do I instantiate like this:
>
> DSingleton singleton = new DSingleton;
>
> Or like this:
>
> DSingleton singleton = singleton.get();
>
> And subsequent calls would be...? The same? Using get() only?
Imho it looks fine.
For creation get() should be always used, since it is the most convenient way to ensure that there is really only one instance of the singleton. Just make this() private, so only you can create new instances:
private this()
{
}
And you probably don't need instantiated_, you can always check whether instance_ is null or not. So:
if (instance_ is null)
{
...
}
else
{
...
}
|
February 02, 2019 Re: Singleton in Action? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ron Tarrant | Thanks for the replies, fellow programmers. (generic, unisex, PC, and all-encompassing) If I could trouble someone for a complete working example so I have something to study, that would be excellent. |
February 02, 2019 Re: Singleton in Action? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ron Tarrant | On Saturday, 2 February 2019 at 19:23:58 UTC, Ron Tarrant wrote: > Thanks for the replies, fellow programmers. (generic, unisex, PC, and all-encompassing) > > If I could trouble someone for a complete working example so I have something to study, that would be excellent. I found here an example: https://rosettacode.org/wiki/Singleton#D Kind regards Andre |
February 02, 2019 Re: Singleton in Action? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Eugene Wissner | On Sat, 02 Feb 2019 17:34:11 +0000, Eugene Wissner wrote:
> For creation get() should be always used, since it is the most convenient way to ensure that there is really only one instance of the singleton. Just make this() private, so only you can create new instances:
>
> private this()
> {
> }
And consider putting the class in its own source file.
|
February 02, 2019 Re: Singleton in Action? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ron Tarrant | On Saturday, 2 February 2019 at 19:23:58 UTC, Ron Tarrant wrote: > Thanks for the replies, fellow programmers. (generic, unisex, PC, and all-encompassing) > > If I could trouble someone for a complete working example so I have something to study, that would be excellent. I think that's what you really need: [1] https://davesdprogramming.wordpress.com/ [2] https://www.youtube.com/watch?v=ZHmIAdlNtiM |
February 03, 2019 Re: Singleton in Action? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ron Tarrant | On Saturday, 2 February 2019 at 16:56:45 UTC, Ron Tarrant wrote: > Hi guys, > > I ran into another snag this morning while trying to implement a singleton. I found all kinds of examples of singleton definitions, but nothing about how to put them into practice. > > [...] If you haven't already been to the d-idioms site it is well worth a look: https://p0nce.github.io/d-idioms/ It has a singleton example that you may find useful. https://p0nce.github.io/d-idioms/#Leveraging-TLS-for-a-fast-thread-safe-singleton bye, norm |
February 03, 2019 Re: Singleton in Action? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ron Tarrant | On Saturday, 2 February 2019 at 16:56:45 UTC, Ron Tarrant wrote:
> Hi guys,
>
> I ran into another snag this morning while trying to implement a singleton. I found all kinds of examples of singleton definitions, but nothing about how to put them into practice.
>
> Can someone show me a code example for how one would actually use a singleton pattern in D? When I did the same thing in PHP, it took me forever to wrap my brain around it, so I'm hoping to get there a little faster this time.
>
> Here's the singleton code I've been playing with:
>
> class DSingleton
> {
> private:
> // Cache instantiation flag in thread-local bool
> // Thread local
> static bool instantiated_;
>
> // Thread global
> __gshared DSingleton instance_;
>
> this()
> {
>
> } // this()
>
> public:
>
> static DSingleton get()
> {
> if(!instantiated_)
> {
> synchronized(DSingleton.classinfo)
> {
> if(!instance_)
> {
> instance_ = new DSingleton();
> writeln("creating");
> }
>
> instantiated_ = true;
> }
> }
> else
> {
> writeln("not created");
> }
>
> return(instance_);
>
> } // DSingleton()
>
> } // class DSingleton
>
> So, my big question is, do I instantiate like this:
>
> DSingleton singleton = new DSingleton;
>
> Or like this:
>
> DSingleton singleton = singleton.get();
>
> And subsequent calls would be...? The same? Using get() only?
Sorry, I should read the post fully before replying, my bad. You access the singleton via the get() function whenever you need it. It is static so there's no need to create a copy of the instance in a "singleton" variable.
DSingleton singleton = new DSingleton; is bad. It bypasses all the checks in the "get()" method to ensure it is a singleton and outside the module where you defined DSingleton it won't compile.
bye,
norm
|
February 03, 2019 Re: Singleton in Action? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ron Tarrant | On Saturday, 2 February 2019 at 16:56:45 UTC, Ron Tarrant wrote:
>
> So, my big question is, do I instantiate like this:
>
> DSingleton singleton = new DSingleton;
>
> Or like this:
>
> DSingleton singleton = singleton.get();
>
> And subsequent calls would be...? The same? Using get() only?
This seems to be a case where D's definition of "private" can cause confusion versus examples from other languages with private as "access only inside the class". In other languages
DSingleton singleton = new DSingleton;
would never compile (the desired behavior), since the constructor is private.
But D allows it in some cases due to "private to class OR module". If DSingleton is in the same module, as for example in a small test program with DSingleton and main() in the same file, then it compiles.
So I think your code is fine, it's just that it can be circumvented - the private constructor can be called - if DSingledton and the instantiating code are in the same module.
|
Copyright © 1999-2021 by the D Language Foundation