Middle
Czym jest dekorator (Decorator) w kontekście programowania i jak jest używany?
sobes.tech AI
Odpowiedź od AI
Dekorator jest wzorcem projektowym strukturalnym, który umożliwia dynamiczne dodawanie nowego zachowania lub obowiązków do obiektów bez modyfikowania ich struktury.
Główne idee:
- Opakowuje istniejący obiekt, rozszerzając jego funkcjonalność.
- Zachowuje interfejs opakowywanego obiektu, zapewniając wymienialność.
- Unika rozrastania się hierarchii klas przy dodawaniu nowych kombinacji zachowań.
Zastosowanie:
- Rozszerzenie funkcjonalności "w locie": Stosuje się, gdy trzeba dodać lub zmienić zachowanie obiektu podczas działania programu.
- Alternatywa dla dziedziczenia: Zamiast tworzyć podklasy dla każdej kombinacji zachowań, używa się dekoratorów. To bardziej elastyczne podejście.
- Kombinacja zachowań: Różne dekoratory mogą być stosowane do tego samego obiektu w różnej kolejności, tworząc unikalne kombinacje.
Przykład w Pythonie:
# Podstawowy komponent
class Component:
def operation(self):
pass
# Konkretna implementacja komponentu
class ConcreteComponent(Component):
def operation(self):
return "ConcreteComponent"
# Podstawowy dekorator (przechowuje odniesienie do opakowywanego obiektu)
class Decorator(Component):
def __init__(self, component):
self._component = component
def operation(self):
return self._component.operation()
# Konkretne dekoratory A i B
class ConcreteDecoratorA(Decorator):
def operation(self):
return f"ConcreteDecoratorA({self._component.operation()})"
class ConcreteDecoratorB(Decorator):
def operation(self):
return f"ConcreteDecoratorB({self._component.operation()})"
# Użycie
simple = ConcreteComponent()
print(simple.operation()) # ConcreteComponent
decorated_a = ConcreteDecoratorA(simple)
print(decorated_a.operation()) # ConcreteDecoratorA(ConcreteComponent)
decorated_b_a = ConcreteDecoratorB(decorated_a)
print(decorated_b_a.operation()) # ConcreteDecoratorB(ConcreteDecoratorA(ConcreteComponent))
Przykład w Pythonie jako cukier składniowy @:
def my_decorator(func):
def wrapper():
print("Przed funkcją")
func()
print("Po funkcji")
return wrapper
@my_decorator
def say_hello():
print("Cześć!")
say_hello()
# Wynik:
# Przed funkcją
# Cześć!
# Po funkcji