-
Notifications
You must be signed in to change notification settings - Fork 172
/
1.srp.py
91 lines (66 loc) · 2.42 KB
/
1.srp.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
"""
Single Responsibility Principle
“…You had one job” — Loki to Skurge in Thor:
Ragnarok
A class should have only one job. If a class has more than one responsibility,
it becomes coupled. A change to one responsibility results to modification of
the other responsibility.
"""
class Animal:
def __init__(self, name: str):
self.name = name
def get_name(self) -> str:
pass
def save(self, animal: Animal):
pass
"""
The Animal class violates the SRP.
How does it violate SRP?
SRP states that classes should have one responsibility, here, we can draw out
two responsibilities: animal database management and animal properties
management. The constructor and get_name manage the Animal properties while the
save manages the Animal storage on a database.
How will this design cause issues in the future?
If the application changes in a way that it affects database management
functions. The classes that make use of Animal properties will have to be
touched and recompiled to compensate for the new changes.
You see this system smells of rigidity, it’s like a domino effect, touch one
card it affects all other cards in line.
To make this conform to SRP, we create another class that will handle the sole
responsibility of storing an animal to a database:
"""
class Animal:
def __init__(self, name: str):
self.name = name
def get_name(self) -> str:
pass
class AnimalDB:
def get_animal(self, id) -> Animal:
pass
def save(self, animal: Animal):
pass
"""
When designing our classes, we should aim to put related features together, so
whenever they tend to change they change for the same reason. And we should try
to separate features if they will change for different reasons. - Steve Fenton
"""
"""
The downside of this solution is that the clients of the this code have to deal
with two classes. A common solution to this dilemma is to apply the Facade
pattern. Animal class will be the Facade for animal database management and
animal properties management.
"""
class Animal:
def __init__(self, name: str):
self.name = name
self.db = AnimalDB()
def get_name(self) -> str:
return self.name
def get(self, id):
return self.db.get_animal(id)
def save(self):
self.db.save(animal=self)
"""
The most important methods are kept in the Animal class and used as Facade for
the lesser functions.
"""