Sobes.tech
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ń.