Middle
O que é um decorador?
sobes.tech IA
Resposta da IA
Um decorador é um padrão de design estrutural que permite adicionar dinamicamente um novo comportamento aos objetos, envolvendo-os em objetos decoradores especiais.
Princípios básicos:
- Composição em vez de herança. O decorador amplia a funcionalidade do objeto sem alterar a sua classe nem usar herança.
- Flexibilidade. Permite adicionar ou remover responsabilidades do objeto em tempo de execução.
- Compatibilidade. Os decoradores e os objetos envolvidos têm uma interface comum, o que permite usá-los de forma intercambiável.
Estrutura:
- Componente (Component): Interface para objetos aos quais podem ser adicionadas responsabilidades dinamicamente.
- Componente concreto (ConcreteComponent): Implementação do Componente.
- Decorador (Decorator): Classe ou interface abstrata que estende o Componente e contém uma referência a um objeto Componente.
- Decoradores concretos (Concrete Decorators): Implementações do Decorador que adicionam comportamentos específicos.
Exemplo (Python):
// Interface do componente
class Coffee:
def get_cost(self):
pass
def get_description(self):
pass
// Componente concreto
class SimpleCoffee(Coffee):
def get_cost(self):
return 1.0
def get_description(self):
return "Café simples"
// Decorador base
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()
// Decorador concreto (Leite)
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() + ", Leite"
// Uso
coffee = SimpleCoffee()
print(f"{coffee.get_description()}: ${coffee.get_cost()}") # Café simples: $1.0
coffee_with_milk = MilkDecorator(coffee)
print(f"{coffee_with_milk.get_description()}: ${coffee_with_milk.get_cost()}") # Café simples, Leite: $1.5
Vantagens:
- Forma mais flexível de ampliar a funcionalidade dos objetos do que a herança.
- Evita a proliferação de subclasses relacionadas à herança.
- Permite adicionar múltiplas "camadas" de comportamento a um único objeto.
Desvantagens:
- Pode complicar o código devido ao grande número de objetos pequenos.
- A ordem de envolvimento pode ser importante.
Aplicação em QA / Automação:
- Adicionar logging aos métodos existentes sem alterar seu código fonte.
- Implementar tratamento de exceções para chamadas específicas.
- Adicionar temporização ou métricas de desempenho.
- Uso em bibliotecas de automação de testes (por exemplo, no padrão Page Object para adicionar verificações ou logs durante a interação com elementos).