Middle
Czym jest dekorator?
sobes.tech AI
Odpowiedź od AI
Dekorator to wzorzec strukturalny, który umożliwia dynamiczne dodawanie nowego zachowania obiektom, opakowując je w specjalne obiekty-dekoratory.
Podstawowe zasady:
- Kompozycja zamiast dziedziczenia. Dekorator rozszerza funkcjonalność obiektu bez zmiany jego klasy i bez użycia dziedziczenia.
- Elastyczność. Pozwala na dodawanie lub usuwanie obowiązków obiektu w czasie działania.
- Zgodność. Dekoratory i opakowywane obiekty mają wspólny interfejs, co pozwala na ich wymienność.
Struktura:
- Komponent (Component): Interfejs dla obiektów, do których można dynamicznie dodawać obowiązki.
- Konkretne komponenty (ConcreteComponent): Implementacja komponentu.
- Dekorator (Decorator): Abstrakcyjna klasa lub interfejs, który rozszerza komponent i zawiera odwołanie do obiektu komponentu.
- Konkretne dekoratory (Concrete Decorators): Implementacje dekoratora, które dodają konkretne zachowania.
Przykład (Python):
// Interfejs komponentu
class Coffee:
def get_cost(self):
pass
def get_description(self):
pass
// Konkretne komponenty
class SimpleCoffee(Coffee):
def get_cost(self):
return 1.0
def get_description(self):
return "Prosta kawa"
// Dekorator bazowy
class CoffeeDecorator(Coffee):
def __init__(self, decorated_coffee):
self._decorated_coffee = decorated_coffee
def get_cost(self):
return self._decorated_coffee.get_cost()
def get_description(self):
return self._decorated_coffee.get_description()
// Konkretne dekoratory (Mleko)
class MilkDecorator(CoffeeDecorator):
def get_cost(self):
return self._decorated_coffee.get_cost() + 0.5
def get_description(self):
return self._decorated_coffee.get_description() + ", Mleko"
// Użycie
coffee = SimpleCoffee()
print(f"{coffee.get_description()}: ${coffee.get_cost()}") # Prosta kawa: $1.0
coffee_with_milk = MilkDecorator(coffee)
print(f"{coffee_with_milk.get_description()}: ${coffee_with_milk.get_cost()}") # Prosta kawa, Mleko: $1.5
Zalety:
- Bardziej elastyczny sposób rozszerzania funkcjonalności obiektów niż dziedziczenie.
- Unika rozrostu podklas związanych z dziedziczeniem.
- Pozwala na dodanie wielu "warstw" zachowania do jednego obiektu.
Wady:
- Może skomplikować kod z powodu dużej liczby małych obiektów.
- Kolejność opakowywania może mieć znaczenie.
Zastosowania w QA / Automatyzacji:
- Dodanie logowania do istniejących metod bez zmiany ich kodu źródłowego.
- Implementacja obsługi wyjątków dla określonych wywołań.
- Dodanie pomiaru czasu lub metryk wydajności.
- Użycie w bibliotekach automatyzacji testów (np. w wzorcu Page Object do dodawania sprawdzeń lub logowania podczas interakcji z elementami).