-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDecorator.py
94 lines (69 loc) · 2.73 KB
/
Decorator.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
from abc import ABC, abstractmethod
class Notifier(ABC):
"""
The base Notifier interface defines operations that can be altered by decorators.
"""
@abstractmethod
def send(self) -> str:
pass
class ConcreteNotifier(Notifier):
"""
Concrete Notifier(s) provide default implementations of the operations. There might be several variations of
these classes.
"""
def send(self) -> str:
return "Concrete Notifier: sending popup notification."
class Decorator(Notifier):
"""
The base Decorator class follows the same interface as the other components.
The primary purpose of this class is to define the wrapping interface for all concrete decorators.
The default implementation of the wrapping code might include a field for storing a wrapped component and the means
to initialize it.
"""
def __init__(self, notifier: Notifier) -> None:
self._notifier = notifier
@property
def notifier(self) -> Notifier:
"""
The Decorator delegates all work to the wrapped component.
"""
return self._notifier
def send(self) -> str:
return self.notifier.send()
class SmsDecorator(Decorator):
"""
Concrete Decorator(s) (like SmsDecoretor and FacebookDecoretor) call the wrapped object and alter its result.
"""
def send(self) -> str:
"""
Decorators may call parent implementation of the operation, instead of calling the wrapped object directly.
This approach simplifies extension of decorator classes.
"""
return f"{self.notifier.send()}" \
f"\n SMS Decorator: sending SMS notification."
class FacebookDecorator(Decorator):
"""
Decorators can execute their behavior either before or after the call to a wrapped object.
"""
def send(self) -> str:
return f"{self.notifier.send()}" \
f"\n Facebook Decorator: sending Facebook notification."
def client_code(notifier: Notifier) -> None:
"""
The client code works with all objects using the Component interface. This way it can stay independent of the
concrete classes of components it works with.
"""
print(f"RESULT:\n {notifier.send()}", end="")
if __name__ == "__main__":
# This way the client code can support both simple components...
simple = ConcreteNotifier()
print("Client: I've got a simple notifier:")
client_code(simple)
print("\n")
# ...as well as decorated ones.
# Decorators can wrap not only simple components but the other decorators as well.
decorator1 = SmsDecorator(simple)
decorator2 = FacebookDecorator(decorator1)
print("Client: Now I've got a decorated notifier:")
client_code(decorator2)
print("\n")