The Singleton design pattern (DP) has a catchy name, but the wrong focus -- on identity rather than on state. The Borg design pattern has all instances share state instead, and Python makes it, literally, a snap.
1 2 3 4 5 | class Borg:
__shared_state = {}
def __init__(self):
self.__dict__ = self.__shared_state
# and whatever else you want in your class -- that's all!
|
The 'Singleton' DP is all about ensuring that just one instance of a certain class is ever created. It has a catchy name and is thus enormously popular, but it's NOT a good idea -- it displays different sorts of problems in different object-models. What we should really WANT, typically, is to let as many instances be created as necessary, BUT all with shared state. Who cares about identity -- it's state (and behavior) we care about!
You can ensure this in many ways in Python, but the Borg design pattern is almost always best. Since the self.__dict__ of any instance can be re-bound, just re-bind it in __init__ to a class-attribute dictionary -- that's all! Now any reference or binding of an instance attribute will actually affect all instances equally -- "we all are one", and all that jazz. Thanks to David Ascher for suggesting the very appropriate name "Borg" for this DP.
Note that __getattr__ and __setattr__ are not involved -- they can be defined independently for whatever other purposes, or left undefined (and __setattr__, if defined, is NOT called for the rebinding of __dict__ itself). This only works with 'classic classes' (all classes in Python 2.1 and earlier, those that don't inherit from built-in types in 2.2 and later), whose instances keep all their per-instance state via self.__dict__ -- 2.2/+ classes with self.__slots__ do not support this idiom quite as smoothly (you can use getters/setters for such advanced-classes to deal with this issue, if you wish, but sticking to 'classic classes' for these needs may be simplest).
Another name... How about Hivemind? I've seen that used in science fiction situations that might fit this concept
Name suggestion. I think the 'Borg' fits this pattern quite well. =)
Should just call it a singleton! The singleton name is correct, even though your Python implementation is neat++.
In Effective C++ by Scott Meyers (item 47) he solves the singleton problem in exactly the same way. The object is created once and then subsquent calls simply return a reference to the original object. In C++ Meyers uses a function wrapper to ensure that it will be declared early enough, but the principle is the same.
In the Design Patterns book the C++ implementation has a class wide Singleton::Instance() function and prevents the constructor being used by making it protected. Same trick.
Coincidently, in an upcoming PHP cookbook web site I am going to publish a singlton pattern that uses the same trick.
yours, Marcus.
It's NOT a singleton object... it doesn't NEED to be! This is a completely and deeply different pattern from Singleton, and thus I find the latest comment totally off-base. Singleton focuses (wrongly) on object IDENTITY: that's what the Gof4 focuses on, that's what "EffC++" focuses on, etc, etc. But we don't really care about identity most of the time, but about state and behavior.
The "Borg" design pattern IS quite possible in C++ (just a bit more laborious, but not much) and was indeed once written up in C++ Report (but I forget the name it was given then and can't find my old issue): you get as many objects as you want, with separate identities but all sharing state and behavior. That's the POINT! Just about all the practical USEFULNESS of Singleton without the troublesome identity-issue that Singleton tends to give.
You loose the encapsulation, readability and explicitness offered by the Singleton. You have a point with the state thing and all, however you do loose the encapsulation offered by the Singleton pattern. You also loose readability and explicitness.
If you take the gof course, your implementation can still return new instances implemented just as you have described.
However, if you take your course it will be much difficult (or impossible) to replace the creation of new instances with a single one.
Also, you loose the explicitness offered by the gof pattern. Clients know that they use a shared object and that it is transient and susceptible to change by others.
Your suggestion might lead to serious misunderstandings (i.e. bugs) in clients of the object (and the external interface exposed to the client is more important than the implementation and the implementers).
quoting... Please calm down.
From GOF4: "...to make the class itself responsible for keeping track of it's sole instance." which does cover your intention.
I probably did not make clear that it was their intention rather than their implementation I was trying to get accross. EffC++ was trying to solve a slightly different problem and recast it as a singleton. It seems pretty clear that both were trying to get around the "new" semantics in their implementations and that your implementation is different. Agreed.
Singleton is a very nice name. Agreed.
Borg is a nice name, but I am not sure that it is exactly right. It could fit a lot of cooperative behaviours as well as "all as one". A thread pool that all worked at the same task would fit.
I could not say which is the more confusing and you will have to just ask lots of programmers as a usability test. I am afraid my personal vote is still for singleton as when I inherit a singleton I know what I want, but when I inherit a Borg I am (a little) less sure.
Please let us know which issue of C++ report it is in when you find it.
yours, Marcus.
inheriting singleton vs inheriting borg. What happens in a large system when two separate subsystems both inherit from (extend) a singleton-class? It's anything but clear to me -- error at runtime, at compiletime, at linktime (none such in Python, let's say at import-time), or what behavior...?
With Borg, it's simplicity itself: as Borg can be instantiated as many times as you want, but all instances share state, each separate subclass may differently override _behavior_, but _state_ will still be collectively shared by all Borg's and sub-Borg's. (Separate sub-Borg classes may of course have class-private state by naming attributes with two leading underscores, as typically done in Python). Easy as pie -- and by that very token, easy to document and explain, too. "All state is shared, identity is indifferent, you'll be assimilated"!-)
This discussion ... ... is getting very long and thin (at least in my browser).
Perhaps additional remarks could appear in a new thread?
Borg vs. Singleton. Alex, isn't this pattern the one you once referred to as "Stateless Proxy"? And, Marcus, Borg is similar to Singleton, except that you separate access and functionality. In C++ you'd still have a static instance of the class that provides the functionality (no loss of encapsulation, then), but it would be private to the Borg class and would only be accessed by the Borg class's member functions.
Borg is indeed 'stateless proxy' Yes Nicola, Borg is the new and improved name (suggested by David Ascher, chief editor of this Cookbook, in a comment above) for the pattern formerly known as 'stateless proxy'.
also known as Monostate. There was an article in the C++ Report several years ago that introduced the Monostate pattern, where all instances share the same state.
The major problem I have found with most implementations of Singletons or Monostates in various languages is that if you need to support multithreading, you have to jump through some fairly major hoops to achieve a good balance of correctness and efficiency.
also known as Monostate. There was an article in the C++ Report several years ago that introduced the Monostate pattern, where all instances share the same state.
The major problem I have found with most implementations of Singletons or Monostates in various languages is that if you need to support multithreading, you have to jump through some fairly major hoops to achieve a good balance of correctness and efficiency.
Borg and more than one module. If you want to use the Borg pattern from more than one module, it works as follows: Extract the Borg Pattern into a module and a class of its own: borg.py:
Let your class in a separate module inherit from Borg and call Borg's initializer in your __init__:
Although sounding like a swedish chef, it works now. The state is shared across all modules using the Test class.
Sorry for the replication. Must've hit add instead of preview somewhere...
Although it looks now like a bug in the Cookbook code... I'm sure I added the last comment only once!
threading. Threading issues really have little to do with Highlander vs Borg (or Singleton vs Monostate if you prefer boring names:-). In Python, it's simplest to devote a thread to handling a bunch of resources that need to be serialized (no matter whether they're wrapped into one or more objects of whatever type), with a Queue of requests on which the devoted-thread (Guardian thread) always sleeps working for requests. All access by working threads to the guardian thread and the resources it protects is by posting to the guardian queue a tuple (response-queue, callable, args, kwds) followed by waiting on the response-queue. Why people would want to conflate this important idiom with the equally important and unrelated idiom of state sharing is a mystery to me, as they work just as well together or separately. What's the contrary of "divide and conquer" -- "conflate and suffer"?-)
Double comments. Sorry there was a bug, its fixed now.
what about GC? Philosophical considerations aside, the "classic" Singleton pattern would seem to perform better than the Borg pattern, when it comes to garbage collection, wouldn't it? What is the point of having the garbage collector keep track of reference counts for a million objects, when one object would suffice?
Singletons using new-style classes.
Just inherit from this class. Everything else is handled automatically.
New-style Borg...
Re: New-style Borg... For those just joining us from Google, use Oren Tirosh's in the comment one above. Two instances of this singleton do not pass the id(a) == id(b) test. Oren's does.
Slight improvement.
Type is now a keyword. And classes can be initialized with params. This handles that.
classes and modules are singletons. You don't need singletons in python simply because classes and modules are always singletons, and they are also first class objects. They can have everything instances have, and as import statements don't make copies there is only ever one of them. We don't need no stinkin' design patterns.
Classes and modules are singeltons, but who prevents us? I agree, but who prevents us from doing stupid things then? Such as instanciating a class, meant to be a singelton within a modul twice?
Classes and modules are singeltons, but who prevents us? : You ! Let's suppose you're implementing a singleton-like class, and you create an instance in your module. You don't want anyone else to be able to create another instance of your class. Just remove the class just after having created your instance ! That's all...
Exemple (in module singleton) :
class MySingleton( object ) : pass
singleton = MySingleton() MySingleton = None
Then, you can use : from singleton import singleton
But you can't do : import singleton singleton.MySingleton()
Of course, you can acces to the class threw the instance. But if you're lurking within the instances to find funny things, you'll have problems everywhere...
You forgot about type. Who can prevent someone from doing type(singleton)(...)?
I think the real solution could be class with classmethods and __new__ raising an Error, then you don't need no instance. But even then someone could have just replaced __new__. :)
simple... If using a class as a singleton, you need http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52304 static methods. You can easily write your __init__ funtion to raise an error.
Singleton is not Borg! :). Oren's approach is Singleton and I implemented a Borg, there is one fundamental difference: Borg are different objects with shared state and Singleton are One object... this may come useful, in more complex examples, a Borg, for instance, can have partial private namespaces, that is, a namespace that is part private (stored in a particular instance) and part shared, this is harder and less intuitive to do with a Singleton pattern.
SemiBorg. What about:
How about a class decorator? Something along the lines of:
Allows you to write this:
This is a nice pattern, but the implication by the author that this pattern is always better than the Singleton pattern is not correct.
As noted already, the Singleton pattern allows for only one instance of the class, whereas this pattern allows many instances with shared state. Often, only a single instance of a class is desired because of memory, particularly in languages without built-in garbage collection, although even in Python, it wouldn't typically make sense to have a million objects when only one Singleton is needed.
All patterns have advantages and disadvantages.
Alex Martelli (author) asked: "What happens in a large system when two separate subsystems both inherit from (extend) a singleton-class? It's anything but clear to me -- error at runtime, at compiletime, at linktime (none such in Python, let's say at import-time), or what behavior...?"
In some languages, such as C++, Singletons are often implemented with a template class. One would never inherit from this class, instead, one would inherit from the class instantiated in the template and create another singleton using the template with that new class.
Of course, once using a singleton, changing to multiple instances is problematic, which is why their use should be sparse - however, they do solve a memory problem that the Monostate (Borg) pattern does not solve.