In the factory pattern you have an object that creates other objects.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | """
A generic factory implementation.
Examples:
>>f=Factory()
>>class A:pass
>>f.register("createA",A)
>>f.createA()
<__main__.A instance at 01491E7C>
>>> class B:
... def __init__(self, a,b=1):
... self.a=a
... self.b=b
...
>>> f.register("createB",B,1,b=2)
>>> f.createB()
>>> b=f.createB()
>>>
>>> b.a
1
>>> b.b
2
>>> class C:
... def __init__(self,a,b,c=1,d=2):
... self.values = (a,b,c,d)
...
>>> f.register("createC",C,1,c=3)
>>> c=f.createC(2,d=4)
>>> c.values
(1, 2, 3, 4)
>>> f.register("importSerialization",__import__,"cPickle")
>>> pickle=f.importSerialization()
>>> pickle
<module 'cPickle' (built-in)>
>>> f.register("importSerialization",__import__,"marshal")
>>> pickle=f.importSerialization()
>>> pickle
<module 'marshal' (built-in)>
>>> f.unregister("importSerialization")
>>> f.importSerialization()
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
AttributeError: Factory instance has no attribute 'importSerialization'
"""
class Factory:
def register(self, methodName, constructor, *args, **kargs):
"""register a constructor"""
_args = [constructor]
_args.extend(args)
setattr(self, methodName,apply(Functor,_args, kargs))
def unregister(self, methodName):
"""unregister a constructor"""
delattr(self, methodName)
class Functor:
def __init__(self, function, *args, **kargs):
assert callable(function), "function should be a callable obj"
self._function = function
self._args = args
self._kargs = kargs
def __call__(self, *args, **kargs):
"""call function"""
_args = list(self._args)
_args.extend(args)
_kargs = self._kargs.copy()
_kargs.update(kargs)
return apply(self._function,_args,_kargs)
|
Factory is useful to separate implementation from interface. It adds a new indirection layer. When you want to instanciate an object you call its factory and the factory creates the instance.
Tags: oop
Abstract Factory? Hmm, can't find my go4 - but this looks to me like the _abstract_ factory pattern rather than the factory pattern. Very nice to see another "design pattern"!
should apply() be replaced. Since apply() is deprecated. Should we:
change to:
and
changed to: