-
Notifications
You must be signed in to change notification settings - Fork 91
/
Copy pathprototype.py
175 lines (123 loc) · 4.29 KB
/
prototype.py
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# Code Listing #7
"""
Protype design pattern and related classes
"""
import copy
from abc import ABCMeta
from borg import Borg
class MetaPrototype(type):
""" A metaclass for Prototypes """
def __init__(cls, *args):
type.__init__(cls, *args)
cls.clone = lambda self: copy.deepcopy(self)
class MetaSingletonPrototype(type):
""" A metaclass for Singleton & Prototype patterns """
def __init__(cls, *args):
print(cls,"__init__ method called with args", args)
type.__init__(cls, *args)
cls.instance = None
cls.clone = lambda self: copy.deepcopy(cls.instance)
def __call__(cls, *args, **kwargs):
if not cls.instance:
print(cls,"creating prototypical instance", args, kwargs)
cls.instance = type.__call__(cls,*args, **kwargs)
return cls.instance
class PrototypeM(metaclass=MetaSingletonPrototype):
""" Top-level prototype class using MetaSingletonPrototype """
pass
class ItemCollection(PrototypeM):
""" An item collection class """
def __init__(self, items=[]):
self.items = items
class Prototype(object):
""" A prototype base class """
def clone(self):
""" Return a clone of self """
return copy.deepcopy(self)
class Register(Prototype):
""" A student Register class """
def __init__(self, names=[]):
self.names = names
class SPrototype(object):
""" A prototype base class using shallow copy """
def clone(self):
""" Return a clone of self """
return copy.copy(self)
class SRegister(SPrototype):
""" Sub-class of SPrototype """
def __init__(self, stuff=(), names=[]):
self.stuff = stuff
self.names = names
class Name(SPrototype):
""" A class representing a person's name """
def __init__(self, first, second):
self.first = first
self.second = second
def __str__(self):
return ' '.join((self.first, self.second))
class Animal(SPrototype):
""" A class representing an animal """
def __init__(self, name, type='Wild'):
self.name = name
self.type = type
def __str__(self):
return ' '.join((str(self.type), self.name))
class Address(SPrototype):
""" An address class """
def __init__(self, building, street, city, zip, country):
self.building = building
self.street = street
self. city = city
self.zip = zip
self.country = country
def __str__(self):
return ', '.join((map(str, (self.building, self.street, self.city, self.zip, self.country))))
class PrototypeFactory(Borg):
""" A Prototype factory/registry class """
def __init__(self):
""" Initializer """
self._registry = {}
def register(self, instance):
""" Register a given instance """
self._registry[instance.__class__] = instance
def clone(self, klass):
""" Return cloned instance of given class """
instance = self._registry.get(klass)
if instance == None:
print('Error:',klass,'not registered')
else:
return instance.clone()
if __name__ == "__main__":
r1 = Register(names=['amy','stu','jack'])
r2 = r1.clone()
print(r1)
print(r2)
print(r1==r2)
r1 = SRegister(names=['amy','stu','jack'])
r2 = r1.clone()
r1.names.append('bob')
print('r1.names==r2.names',r1.names==r2.names)
print('r1.names is r2.names',r1.names is r2.names)
i1 = ItemCollection(items=['apples','grapes','oranges'])
print(i1)
# Invokes the Prototype API
i2 = i1.clone()
print('i1.items is i2.items',i1.items is i2.items)
# Invokes the Singleton API
i3 = ItemCollection(items=['apples','grapes','oranges'])
print('i1 is i3',i1 is i3)
# Illustrating factory
name = Name('Bill', 'Bryson')
animal = Animal('Elephant')
factory = PrototypeFactory()
factory.register(animal)
factory.register(name)
# Clone them
name2 = factory.clone(Name)
animal2 = factory.clone(Animal)
print(name, name2)
print(animal, animal2)
print('name is not name2',name is not name2)
print('animal is not animal2',animal is not animal2)
class C: pass
factory.clone(C)