forked from Sean-Bradley/Design-Patterns-In-Python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprototype.py
More file actions
89 lines (71 loc) · 2.6 KB
/
prototype.py
File metadata and controls
89 lines (71 loc) · 2.6 KB
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
"""
Prototype design pattern is good for when creating a new object
may require more resources than you want to use or have available,
versus just making a new copy in memory.
Eg, A file you've downloaded from a server may be large, but
since it is already in memory, you could just clone it, and
work on the new copy independently of the original.
In the prototype patterns interface, you create a static clone method that
should be implemented by all classes that use the interface.
How the clone method is implemented in the concrete class is up to you.
You will need to decide whether a shallow or deep copy is required.
A shallow copy, copies and creates new references 1 level deep,
A deep copy, copies and creates new references for all levels.
In Python you have mutable objects such as Lists, Dictionaries,
Sets and any custom Objects you have created. A shallow copy,
will create new copies of the objects with new references in memory,
but the underlying data will point to the same location as the original
copy. Be sure to test your implementation that
the copy method you use works as expected.
"""
from abc import ABCMeta, abstractstaticmethod
import copy
class IProtoType(metaclass=ABCMeta):
"""interface with clone method"""
@abstractstaticmethod
def clone():
"""The clone, deep or shallow, is up to how you
want implement the details in your concrete class?"""
class ConcreteClass1(IProtoType):
"""concrete class 1"""
def __init__(self, i=0, s="", l=[], d={}):
self.i = i
self.s = s
self.l = l
self.d = d
def clone(self):
return type(self)(
self.i,
self.s,
self.l.copy(),
self.d.copy())
def __str__(self):
return f"{id(self)}\ti={self.i}\ts={self.s}\tl={self.l}\td={self.d}"
class ConcreteClass2(IProtoType):
"""concrete class 2"""
def __init__(self, i=0, s="", l=[], d={}):
self.i = i
self.s = s
self.l = l
self.d = d
def clone(self):
return type(self)(
self.i,
self.s,
copy.deepcopy(self.l),
copy.deepcopy(self.d))
def __str__(self):
return f"i={self.i}\t\ts={self.s}\tl={self.l}\td={self.d}\n{id(self.i)}\t{id(self.s)}\t{id(self.l)}\t{id(self.d)}\t"
if __name__ == "__main__":
OBJECT1 = ConcreteClass1(
1,
"OBJECT1",
[1, 2, 3],
{"a": 4, "b": 5, "c": 6}
)
print(f"OBJECT1 {OBJECT1}")
OBJECT2 = OBJECT1.clone()
OBJECT2.s = "OBJECT2"
OBJECT2.l[0] = 10
print(f"OBJECT2 {OBJECT2}")
print(f"OBJECT1 {OBJECT1}")