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