mailRe: Vote for the design of the relax data storage object singleton.


Others Months | Index by Date | Thread Index
>>   [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Header


Content

Posted by Chris MacRaild on March 26, 2007 - 11:13:
On Mon, 2007-03-26 at 14:53 +1000, Edward d'Auvergne wrote:
On 3/23/07, Chris MacRaild <c.a.macraild@xxxxxxxxxxx> wrote:
On Fri, 2007-03-23 at 14:59 +1100, Edward d'Auvergne wrote:
If the base class cannot be a singleton due to the derived class objects
being instances of it, then how can the three different values of 'x'
below be explained?

Please state specifically what conflict you see between these two ideas,
because, as I've said several times already, I can see none.

The singleton is a single distinct object within the program which can
only exist once.  Any subsequent attempts to instantiate the class
returns the reference (or pointer in C speak) to that object.  The
example below demonstrates three distinct objects (all values of the
variable 'x' are different).  Whether or not there has been
inheritance between the classes is inconsequential.  Whether or not
you use the word 'instance' it is the three distinct objects that make
the three distinct singletons.  Trying to instantiate the three again
just returns the references and hence the three different values of
'x' exist in the new references.   A singleton is an object and there
is only one of it.


No. A singleton is a class that can only ever have one instance.

By your definition, all objects are singletons, because there is only
ever one of any object.





$ python
Python 2.4.1 (#2, Oct  6 2006, 15:14:48)
[GCC 4.0.1 (4.0.1-5mdk for Mandriva Linux release 2006.0)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
from Queue import Queue

class ThreadQueue(Queue, object):
...     instances = {}
...     def __new__(cls, *args, **kargs):
...         if ThreadQueue.instances.get(cls) is None:
...             ThreadQueue.instances[cls] = object.__new__(cls, *args,
**kargs)
...         return ThreadQueue.instances[cls]
...
class ResultsQueue(ThreadQueue):
...     mf_results = {}
...
class OptimisationQueue(ThreadQueue):
...     min_instances = []
...

# Create the three singletons.
... thread_queue = ThreadQueue()
results_queue = ResultsQueue()
opt_queue = OptimisationQueue()

# Show that the singletons have different locations in memory - i.e.
are different instances.
... print id(thread_queue)
1077833228
print id(results_queue)
1077867628
print id(opt_queue)
1077881612

# Add objects to the singletons.
... thread_queue.x = 1
results_queue.x = 2
opt_queue.x = 3

# Print the objects of the singletons.
... print thread_queue.x
1
print results_queue.x
2
print opt_queue.x
3


So, at this point we have three classes: ThreadQueue, ResultsQueue and
OptimisationQueue. We have three objects, which are class instances:
thread_queue, results_queue and opt_queue. We are in full agreement that
these are three different objects, so there is no suprise that you can
create an attribute of the same name in each object, and bind that
attribute to different values. Attributes of different objects are
themselves different objects, and there is no common namespace, so all
three attributes can have the same name without conflict. All of this
has nothing to do with the fact that results_queue has instancehood
relationships both with ResultsQueue and with ThreadQueue, and opt_queue
has has instancehood relationships both with ResultsQueue and with
OptimisationQueue.

The 'instancehood relationships' have nothing to do with the three
singletons - i.e. the three distinct objects which can exist only in
one copy.  I don't believe an object to be instances of its base
classes but rather the base classes are searched recursively for
attributes if the attribute isn't in the derived class (it's a scope
thing).  But even if it is, the example still demonstrates inheritance
together with 3 different objects which only ever exist once in the
program.  This shows that both the two classes and their base class
(which defines the singleton and queuing behaviour) are three distinct
singletons.


'instancehood relationships' are central to the definition of the
singleton design pattern. Again, a singleton is a class with only ever
one instance. Your ThreadQueue is not a singleton because:

isinstance(thread_queue, ThreadQueue)
True
isinstance(results_queue, ThreadQueue)
True
thread_queue is results_queue
False

We have two different objects, both instances of ThreadQueue. Therefore
the design pattern is broken.



print results_queue is thread_queue
False
print opt_queue is thread_queue
False
print results_queue is opt_queue
False

# Instantiate the three singletons again.

This is a contradiction in terms! If they are singletons, you instatiate
once and once only. Any attempt to do otherwise should either raise an
exception, or simply return the single existing instance of the class.
You have coded the second option, so ...

The instantiation returns references to the singleton object.  There's
nothing wrong with that, the class is only ever instantiated once.


... thread_queue2 = ThreadQueue()
results_queue2 = ResultsQueue()
opt_queue2 = OptimisationQueue()

You have simply rebound thread_queue as thread_queue2, results_queue as
results_queue2 and opt_queue as opt_queue2. So...

This, together with the print statements below demonstrate 3
singletons - i.e. 3 objects which exist only once in the program.



# Print the objects of the singletons.
... print thread_queue2.x
1
print results_queue2.x
2
print opt_queue2.x
3


This follows obviously:

thread_queue is thread_queue2
True
results_queue is results_queue2
True
opt_queue is opt_queue2

so:

thread_queue.x is thread_queue2.x
True

etc.


Again, where is the conflict?

There is no conflict.  This demonstrates three distinct objects and
hence three distinct singletons.

All objects are distinct, whether singletons or not. Three distinct
objects does not demonstrate three singletons.


Edward





Related Messages


Powered by MHonArc, Updated Mon Mar 26 18:20:40 2007