Sobes.tech
Middle

O que é um decorador (Decorator) no contexto da programação e como é que ele é utilizado?

sobes.tech IA

Resposta da IA

O decorador é um padrão de design estrutural que permite adicionar dinamicamente um novo comportamento ou responsabilidades aos objetos sem modificar a sua estrutura.

Ideias principais:

  • Envolve um objeto existente, expandindo a sua funcionalidade.
  • Mantém a interface do objeto envolvido, garantindo a intercambialidade.
  • Evita a proliferação de hierarquias de classes ao adicionar novas combinações de comportamentos.

Utilização:

  1. Expansão de funcionalidade "em tempo de execução": Aplicado quando é necessário adicionar ou alterar o comportamento de um objeto durante a execução do programa.
  2. Alternativa à herança: Em vez de criar subclasses para cada combinação de comportamentos, usam-se decoradores. É uma abordagem mais flexível.
  3. Combinação de comportamentos: Diferentes decoradores podem ser aplicados ao mesmo objeto em ordens diferentes, criando combinações únicas.

Exemplo em Python:

# Componente base
class Component:
    def operation(self):
        pass

# Componente concreto
class ConcreteComponent(Component):
    def operation(self):
        return "ConcreteComponent"

# Decorador base (armazena uma referência ao objeto envolvido)
class Decorator(Component):
    def __init__(self, component):
        self._component = component

    def operation(self):
        return self._component.operation()

# Decorador concreto A
class ConcreteDecoratorA(Decorator):
    def operation(self):
        return f"ConcreteDecoratorA({self._component.operation()})"

# Decorador concreto B
class ConcreteDecoratorB(Decorator):
    def operation(self):
        return f"ConcreteDecoratorB({self._component.operation()})"

# Uso
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))

Exemplo em Python como açúcar sintático @:

def my_decorator(func):
    def wrapper():
        print("Antes da função")
        func()
        print("Depois da função")
    return wrapper

@my_decorator
def say_hello():
    print("Olá!")

say_hello()
# Saída:
# Antes da função
# Olá!
# Depois da função