mirror of
https://github.com/rjNemo/design-patterns
synced 2026-06-06 02:26:40 +00:00
add decorator code example
This commit is contained in:
parent
e284959e94
commit
196a20bc66
8 changed files with 97 additions and 0 deletions
0
__init__.py
Normal file
0
__init__.py
Normal file
0
structural/__init__.py
Normal file
0
structural/__init__.py
Normal file
0
structural/decorator/__init__.py
Normal file
0
structural/decorator/__init__.py
Normal file
8
structural/decorator/component.py
Normal file
8
structural/decorator/component.py
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
class Component:
|
||||||
|
"""
|
||||||
|
The base Component interface defines operations that can be altered by
|
||||||
|
decorators.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def operation(self) -> str:
|
||||||
|
pass
|
||||||
10
structural/decorator/concrete_component.py
Normal file
10
structural/decorator/concrete_component.py
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
from component import Component
|
||||||
|
|
||||||
|
class ConcreteComponent(Component):
|
||||||
|
"""
|
||||||
|
Concrete Components provide default implementations of the operations. There
|
||||||
|
might be several variations of these classes.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def operation(self) -> str:
|
||||||
|
return "ConcreteComponent"
|
||||||
26
structural/decorator/concrete_decorators.py
Normal file
26
structural/decorator/concrete_decorators.py
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
from decorator import Decorator
|
||||||
|
|
||||||
|
|
||||||
|
class ConcreteDecoratorA(Decorator):
|
||||||
|
"""
|
||||||
|
Concrete Decorators call the wrapped object and alter its result in some
|
||||||
|
way.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def operation(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"ConcreteDecoratorA({self.component.operation()})"
|
||||||
|
|
||||||
|
|
||||||
|
class ConcreteDecoratorB(Decorator):
|
||||||
|
"""
|
||||||
|
Decorators can execute their behavior either before or after the call to a
|
||||||
|
wrapped object.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def operation(self) -> str:
|
||||||
|
return f"ConcreteDecoratorB({self.component.operation()})"
|
||||||
23
structural/decorator/decorator.py
Normal file
23
structural/decorator/decorator.py
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
from component import Component
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Decorator(Component):
|
||||||
|
"""
|
||||||
|
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.
|
||||||
|
"""
|
||||||
|
|
||||||
|
_component: Component
|
||||||
|
|
||||||
|
@property
|
||||||
|
def component(self) -> Component:
|
||||||
|
"""The Decorator delegates all work to the wrapped component."""
|
||||||
|
return self._component
|
||||||
|
|
||||||
|
def operation(self) -> str:
|
||||||
|
return self._component.operation()
|
||||||
30
structural/decorator/main.py
Normal file
30
structural/decorator/main.py
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
from component import Component
|
||||||
|
from concrete_component import ConcreteComponent
|
||||||
|
from concrete_decorators import ConcreteDecoratorA, ConcreteDecoratorB
|
||||||
|
|
||||||
|
|
||||||
|
def client_code(component: Component):
|
||||||
|
"""
|
||||||
|
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: {component.operation()}", end='')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
# This way the client code can support both simple components...
|
||||||
|
simple = ConcreteComponent()
|
||||||
|
print("Client: I've got a simple component:")
|
||||||
|
client_code(simple)
|
||||||
|
print("\n")
|
||||||
|
|
||||||
|
# ...as well as decorated ones.
|
||||||
|
|
||||||
|
# Note how decorators can wrap not only simple components but the other
|
||||||
|
# decorators as well.
|
||||||
|
decorator1 = ConcreteDecoratorA(simple)
|
||||||
|
decorator2 = ConcreteDecoratorB(decorator1)
|
||||||
|
print("Client: Now I've got a decorated component:")
|
||||||
|
client_code(decorator2)
|
||||||
Loading…
Reference in a new issue