Middle
Czym jest dekorator (Decorator)?
sobes.tech AI
Odpowiedź od AI
Dekorator jest wzorcem strukturalnym, który umożliwia dynamiczne dodawanie nowej funkcjonalności do obiektu, nie zmieniając jego struktury. Opakowuje obiekt, zapewniając ten sam interfejs co opakowywany obiekt, jednocześnie dodając lub modyfikując jego zachowanie.
Główne elementy:
- Komponent (Component): Interfejs lub klasa abstrakcyjna definiująca wspólną funkcjonalność dla opakowywanych obiektów i dekoratorów.
- Konkretna komponent (Concrete Component): Implementacja komponentu, podstawowy obiekt, do którego dodawana jest funkcjonalność.
- Dekorator (Decorator): Klasa abstrakcyjna implementująca interfejs komponentu i zawierająca odwołanie do obiektu komponentu.
- Konkretny dekorator (Concrete Decorator): Implementacja dekoratora, dodająca specyficzną funkcjonalność przed lub po wywołaniu metody opakowywanego obiektu.
Przykład w Python:
# Komponent
class Coffee:
def get_cost(self):
return 5 # Podstawowy koszt kawy
def get_description(self):
return "Prosta kawa"
# Konkretna klasa komponentu
class SimpleCoffee(Coffee):
pass
# Dekorator
class CoffeeDecorator(Coffee):
def __init__(self, coffee):
self._coffee = coffee
def get_cost(self):
return self._coffee.get_cost()
def get_description(self):
return self._coffee.get_description()
# Konkretny dekorator
class MilkDecorator(CoffeeDecorator):
def get_cost(self):
return self._coffee.get_cost() + 2 # Dodajemy koszt mleka
def get_description(self):
return self._coffee.get_description() + ", Mleko"
# Użycie
# simple_coffee = SimpleCoffee()
# print(f"Koszt: {simple_coffee.get_cost()}, Opis: {simple_coffee.get_description()}")
# coffee_with_milk = MilkDecorator(simple_coffee)
# print(f"Koszt: {coffee_with_milk.get_cost()}, Opis: {coffee_with_milk.get_description()}")
Zalety:
- Elastyczność: Funkcjonalność dodawana jest w czasie działania.
- Unikanie podklas: Pozwala uniknąć tworzenia wielu podklas dla każdej kombinacji zachowań.
- Rozdzielenie odpowiedzialności: Każde dodanie zachowania jest realizowane w osobnej klasie.
Wady:
- Może zwiększyć liczbę klas.
- Debugowanie może być trudniejsze z powodu łańcucha opakowań.