0% found this document useful (0 votes)
6 views22 pages

Fundamentos de Padrões de Design

The document outlines essential design patterns in software development, categorized into creational, structural, and behavioral patterns. It includes detailed explanations and code examples for patterns such as Singleton, Factory Method, Builder, Adapter, Decorator, and Strategy. Additionally, it discusses the use cases and scenarios for implementing these patterns effectively.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views22 pages

Fundamentos de Padrões de Design

The document outlines essential design patterns in software development, categorized into creational, structural, and behavioral patterns. It includes detailed explanations and code examples for patterns such as Singleton, Factory Method, Builder, Adapter, Decorator, and Strategy. Additionally, it discusses the use cases and scenarios for implementing these patterns effectively.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

# FUNDAMENTOS: DESIGN PATTERNS ESSENCIAIS

**Padrões de Design Mais Usados na Prática**

---

## ÍNDICE

1. [Padrões Criacionais](#1-padrões-criacionais)
2. [Padrões Estruturais](#2-padrões-estruturais)
3. [Padrões Comportamentais](#3-padrões-comportamentais)
4. [Padrões Arquiteturais](#4-padrões-arquiteturais)
5. [Anti-Patterns](#5-anti-patterns)

---

## 1. PADRÕES CRIACIONAIS

### 1.1) Singleton

```python
"""
SINGLETON: Garante que classe tenha apenas UMA instância.

Quando usar:
Configuration manager
Database connection pool
Logger
Cache global

Quando NÃO usar:


Estado compartilhado desnecessário
Dificulta testes
Geralmente um code smell
"""

class DatabaseConnection:
"""Singleton: Uma única conexão de database."""

_instance = None
_connection = None

def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance

def connect(self, connection_string: str):


"""Conecta ao banco."""
if self._connection is None:
self._connection = create_connection(connection_string)
return self._connection

# Uso
db1 = DatabaseConnection()
db2 = DatabaseConnection()

assert db1 is db2 # Mesma instância!

# ALTERNATIVA MODERNA (Python): Module-level singleton

# [Link]
_connection = None

def get_connection(connection_string: str):


"""Singleton via module."""
global _connection
if _connection is None:
_connection = create_connection(connection_string)
return _connection

# Uso
from database import get_connection
conn = get_connection("postgresql://...")
1.2) Factory Method
"""
FACTORY METHOD: Delega criação de objetos para subclasses.

Quando usar:
Múltiplas implementações de interface
Criação complexa
Dependente de configuração
"""

from abc import ABC, abstractmethod

# Produto abstrato
class PaymentProcessor(ABC):
@abstractmethod
def process(self, amount: float) -> bool:
pass

# Produtos concretos
class CreditCardProcessor(PaymentProcessor):
def process(self, amount: float) -> bool:
print(f"Processing ${amount} via Credit Card")
return True

class PayPalProcessor(PaymentProcessor):
def process(self, amount: float) -> bool:
print(f"Processing ${amount} via PayPal")
return True

class PIXProcessor(PaymentProcessor):
def process(self, amount: float) -> bool:
print(f"Processing R${amount} via PIX")
return True

# Factory
class PaymentProcessorFactory:
"""Factory Method pattern."""

@staticmethod
def create(payment_method: str) -> PaymentProcessor:
"""Cria processor baseado em string."""
if payment_method == "credit_card":
return CreditCardProcessor()
elif payment_method == "paypal":
return PayPalProcessor()
elif payment_method == "pix":
return PIXProcessor()
else:
raise ValueError(f"Unknown payment method: {payment_method}")

# Uso
processor = [Link]("pix")
[Link](100.00) # PIX processor!

# VARIAÇÃO: Abstract Factory (família de objetos relacionados)

class UIFactory(ABC):
"""Abstract Factory para componentes UI."""

@abstractmethod
def create_button(self) -> 'Button':
pass

@abstractmethod
def create_checkbox(self) -> 'Checkbox':
pass

class WindowsUIFactory(UIFactory):
def create_button(self) -> 'Button':
return WindowsButton()

def create_checkbox(self) -> 'Checkbox':


return WindowsCheckbox()

class MacOSUIFactory(UIFactory):
def create_button(self) -> 'Button':
return MacOSButton()

def create_checkbox(self) -> 'Checkbox':


return MacOSCheckbox()

# Cliente usa factory sem saber implementação


def render_ui(factory: UIFactory):
button = factory.create_button()
checkbox = factory.create_checkbox()
[Link]()
[Link]()
1.3) Builder
"""
BUILDER: Constrói objetos complexos passo a passo.

Quando usar:
Objeto com muitos parâmetros opcionais
Construção em etapas
Múltiplas representações do mesmo objeto
"""

from dataclasses import dataclass


from typing import Optional

@dataclass
class Pizza:
"""Produto complexo."""
size: str
crust: str
cheese: bool = False
pepperoni: bool = False
mushrooms: bool = False
olives: bool = False
sauce: str = "tomato"

class PizzaBuilder:
"""Builder para Pizza."""

def __init__(self):
self._pizza = None

def reset(self):
"""Reseta builder."""
self._pizza = Pizza(size="medium", crust="regular")
return self

def set_size(self, size: str):


"""Define tamanho."""
self._pizza.size = size
return self # Fluent interface!

def set_crust(self, crust: str):


"""Define massa."""
self._pizza.crust = crust
return self

def add_cheese(self):
"""Adiciona queijo."""
self._pizza.cheese = True
return self
def add_pepperoni(self):
"""Adiciona pepperoni."""
self._pizza.pepperoni = True
return self

def add_mushrooms(self):
"""Adiciona cogumelos."""
self._pizza.mushrooms = True
return self

def set_sauce(self, sauce: str):


"""Define molho."""
self._pizza.sauce = sauce
return self

def build(self) -> Pizza:


"""Retorna pizza construída."""
pizza = self._pizza
[Link]() # Prepara para próxima pizza
return pizza

# Uso (Fluent Interface)


builder = PizzaBuilder()

pizza1 = (builder
.reset()
.set_size("large")
.set_crust("thin")
.add_cheese()
.add_pepperoni()
.add_mushrooms()
.build())

pizza2 = (builder
.reset()
.set_size("small")
.add_cheese()
.build())

# VARIAÇÃO: Director (encapsula construção comum)

class PizzaDirector:
"""Director para pizzas comuns."""

def __init__(self, builder: PizzaBuilder):


[Link] = builder

def make_margherita(self) -> Pizza:


"""Pizza Margherita pré-definida."""
return ([Link]
.reset()
.set_size("medium")
.add_cheese()
.set_sauce("tomato")
.build())

def make_pepperoni(self) -> Pizza:


"""Pizza Pepperoni pré-definida."""
return ([Link]
.reset()
.set_size("large")
.add_cheese()
.add_pepperoni()
.build())

director = PizzaDirector(PizzaBuilder())
margherita = director.make_margherita()

2. PADRÕES ESTRUTURAIS
2.1) Adapter
"""
ADAPTER: Converte interface de classe para outra esperada.

Quando usar:
Integração com código legado
API de terceiros incompatível
Múltiplas implementações com interfaces diferentes
"""

# Sistema legado
class LegacyPaymentSystem:
"""Sistema antigo com interface diferente."""

def make_payment(self, card_number: str, amount_cents: int):


"""Processa pagamento (valor em centavos)."""
print(f"Legacy: Processing {amount_cents} cents")
return {"success": True, "transaction_id": "12345"}

# Interface moderna esperada


class PaymentProcessor(ABC):
@abstractmethod
def process_payment(self, amount: float) -> str:
"""Processa pagamento (valor em reais)."""
pass

# Adapter
class LegacyPaymentAdapter(PaymentProcessor):
"""Adapta sistema legado para interface moderna."""

def __init__(self, legacy_system: LegacyPaymentSystem):


self.legacy_system = legacy_system
def process_payment(self, amount: float) -> str:
"""Implementa interface moderna."""
# Converte reais centavos
amount_cents = int(amount * 100)

# Chama sistema legado


result = self.legacy_system.make_payment(
card_number="****",
amount_cents=amount_cents
)

# Converte response
return result["transaction_id"]

# Uso
legacy = LegacyPaymentSystem()
adapter = LegacyPaymentAdapter(legacy)

# Cliente usa interface moderna


transaction_id = adapter.process_payment(100.50) # R$ 100.50

# EXEMPLO 2: Adapter para API externa

import requests

class StripeAdapter(PaymentProcessor):
"""Adapta Stripe API para nossa interface."""

def __init__(self, api_key: str):


self.api_key = api_key

def process_payment(self, amount: float) -> str:


"""Chama Stripe API."""
response = [Link](
"[Link]
auth=(self.api_key, ""),
data={
"amount": int(amount * 100), # Converte para centavos
"currency": "brl"
}
)
return [Link]()["id"]
2.2) Decorator
"""
DECORATOR: Adiciona responsabilidades a objetos dinamicamente.

Quando usar:
Adicionar funcionalidade sem modificar classe
Combinar funcionalidades flexivelmente
Single Responsibility Principle
"""

from abc import ABC, abstractmethod


from functools import wraps
import time

# Component
class Coffee(ABC):
@abstractmethod
def cost(self) -> float:
pass

@abstractmethod
def description(self) -> str:
pass

# Concrete Component
class SimpleCoffee(Coffee):
def cost(self) -> float:
return 5.0

def description(self) -> str:


return "Simple Coffee"

# Decorator Base
class CoffeeDecorator(Coffee):
def __init__(self, coffee: Coffee):
self._coffee = coffee

# Concrete Decorators
class MilkDecorator(CoffeeDecorator):
def cost(self) -> float:
return self._coffee.cost() + 2.0

def description(self) -> str:


return self._coffee.description() + ", Milk"

class SugarDecorator(CoffeeDecorator):
def cost(self) -> float:
return self._coffee.cost() + 0.5

def description(self) -> str:


return self._coffee.description() + ", Sugar"

class WhippedCreamDecorator(CoffeeDecorator):
def cost(self) -> float:
return self._coffee.cost() + 3.0

def description(self) -> str:


return self._coffee.description() + ", Whipped Cream"

# Uso (composição dinâmica!)


coffee = SimpleCoffee()
print(f"{[Link]()}: R$ {[Link]()}")
# Simple Coffee: R$ 5.0

coffee_with_milk = MilkDecorator(coffee)
print(f"{coffee_with_milk.description()}: R$ {coffee_with_milk.cost()}")
# Simple Coffee, Milk: R$ 7.0

fancy_coffee = WhippedCreamDecorator(
SugarDecorator(
MilkDecorator(SimpleCoffee())
)
)
print(f"{fancy_coffee.description()}: R$ {fancy_coffee.cost()}")
# Simple Coffee, Milk, Sugar, Whipped Cream: R$ 10.5

# PYTHON DECORATOR (função)

def timer(func):
"""Decorator de função: mede tempo de execução."""
@wraps(func)
def wrapper(*args, **kwargs):
start = [Link]()
result = func(*args, **kwargs)
end = [Link]()
print(f"{func.__name__} took {end - start:.2f}s")
return result
return wrapper

@timer
def slow_function():
[Link](2)
return "Done"

slow_function() # Imprime: slow_function took 2.00s

def retry(max_attempts: int = 3):


"""Decorator parametrizado: retry."""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for attempt in range(max_attempts):
try:
return func(*args, **kwargs)
except Exception as e:
if attempt == max_attempts - 1:
raise
print(f"Attempt {attempt + 1} failed: {e}")
return wrapper
return decorator

@retry(max_attempts=3)
def unstable_function():
import random
if [Link]() < 0.7:
raise Exception("Random failure")
return "Success"
2.3) Facade
"""
FACADE: Interface simplificada para subsistema complexo.

Quando usar:
Simplificar API complexa
Desacoplar cliente de subsistemas
Criar ponto de entrada único
"""

# Subsistemas complexos

class ProductCatalog:
def check_availability(self, product_id: str) -> bool:
print(f"Checking availability of {product_id}")
return True

class InventorySystem:
def reserve(self, product_id: str, quantity: int):
print(f"Reserving {quantity} of {product_id}")
return f"reservation_{product_id}"

class PaymentGateway:
def process(self, amount: float) -> str:
print(f"Processing payment of ${amount}")
return "payment_123"

class ShippingService:
def schedule(self, address: str, items: list):
print(f"Scheduling shipment to {address}")
return "shipment_456"

class NotificationService:
def send_email(self, email: str, message: str):
print(f"Sending email to {email}")

# FACADE (simplifica interação)

class OrderFacade:
"""
Facade para processo de pedido.

Esconde complexidade de múltiplos subsistemas.


"""

def __init__(self):
[Link] = ProductCatalog()
[Link] = InventorySystem()
[Link] = PaymentGateway()
[Link] = ShippingService()
[Link] = NotificationService()

def place_order(
self,
product_id: str,
quantity: int,
payment_amount: float,
shipping_address: str,
customer_email: str
) -> dict:
"""
Método simples que coordena múltiplos subsistemas.

Cliente chama apenas 1 método!


"""
# 1. Verificar disponibilidade
if not [Link].check_availability(product_id):
return {"success": False, "error": "Product unavailable"}

# 2. Reservar estoque
reservation_id = [Link](product_id, quantity)

# 3. Processar pagamento
try:
payment_id = [Link](payment_amount)
except Exception:
# Rollback
[Link].cancel_reservation(reservation_id)
return {"success": False, "error": "Payment failed"}

# 4. Agendar envio
shipment_id = [Link](
shipping_address,
[{"product_id": product_id, "quantity": quantity}]
)

# 5. Notificar cliente
[Link].send_email(
customer_email,
f"Order confirmed! Shipment: {shipment_id}"
)

return {
"success": True,
"payment_id": payment_id,
"shipment_id": shipment_id
}

# Uso (cliente não precisa conhecer subsistemas!)


facade = OrderFacade()

result = facade.place_order(
product_id="NOTEBOOK-123",
quantity=1,
payment_amount=3000.0,
shipping_address="Rua A, 123",
customer_email="customer@[Link]"
)

# UMA chamada coordena 5 subsistemas!

3. PADRÕES COMPORTAMENTAIS
3.1) Strategy
"""
STRATEGY: Define família de algoritmos intercambiáveis.

Quando usar:
Múltiplos algoritmos para mesma tarefa
Evitar condicionais complexos (if/else)
Algoritmo pode mudar em runtime
"""

from abc import ABC, abstractmethod

# Strategy interface
class DiscountStrategy(ABC):
@abstractmethod
def calculate(self, amount: float) -> float:
"""Calcula desconto."""
pass

# Concrete Strategies
class NoDiscountStrategy(DiscountStrategy):
def calculate(self, amount: float) -> float:
return 0.0

class PercentageDiscountStrategy(DiscountStrategy):
def __init__(self, percentage: float):
[Link] = percentage

def calculate(self, amount: float) -> float:


return amount * ([Link] / 100)

class FixedDiscountStrategy(DiscountStrategy):
def __init__(self, discount_amount: float):
self.discount_amount = discount_amount

def calculate(self, amount: float) -> float:


return min(self.discount_amount, amount)

class VIPDiscountStrategy(DiscountStrategy):
"""Desconto especial: 20% + R$ 50."""

def calculate(self, amount: float) -> float:


percentage_discount = amount * 0.20
return percentage_discount + 50.0

# Context
class ShoppingCart:
def __init__(self, discount_strategy: DiscountStrategy):
[Link] = []
self.discount_strategy = discount_strategy

def add_item(self, price: float):


[Link](price)

def set_discount_strategy(self, strategy: DiscountStrategy):


"""Troca estratégia em runtime!"""
self.discount_strategy = strategy

def calculate_total(self) -> float:


subtotal = sum([Link])
discount = self.discount_strategy.calculate(subtotal)
return subtotal - discount

# Uso
cart = ShoppingCart(NoDiscountStrategy())
cart.add_item(100.0)
cart.add_item(50.0)

print(f"Total: R$ {cart.calculate_total()}") # R$ 150.00

# Troca estratégia dinamicamente


cart.set_discount_strategy(PercentageDiscountStrategy(10))
print(f"Total com 10% desconto: R$ {cart.calculate_total()}") # R$ 135.00

cart.set_discount_strategy(VIPDiscountStrategy())
print(f"Total VIP: R$ {cart.calculate_total()}") # R$ 70.00
3.2) Observer
"""
OBSERVER: Define dependência 1-para-N entre objetos.

Quando usar:
Mudança em um objeto deve notificar outros
Pub/Sub pattern
Event-driven architecture
"""

from abc import ABC, abstractmethod


from typing import List

# Observer interface
class Observer(ABC):
@abstractmethod
def update(self, subject: 'Subject') -> None:
pass

# Subject (Observable)
class Subject:
def __init__(self):
self._observers: List[Observer] = []
self._state = None

def attach(self, observer: Observer):


"""Registra observer."""
self._observers.append(observer)

def detach(self, observer: Observer):


"""Remove observer."""
self._observers.remove(observer)

def notify(self):
"""Notifica todos observers."""
for observer in self._observers:
[Link](self)

@property
def state(self):
return self._state

@[Link]
def state(self, value):
"""Quando estado muda, notifica observers."""
self._state = value
[Link]()

# Concrete Observers
class EmailObserver(Observer):
def update(self, subject: Subject):
print(f" EmailObserver: State changed to {[Link]}")
# Envia email

class SMSObserver(Observer):
def update(self, subject: Subject):
print(f" SMSObserver: State changed to {[Link]}")
# Envia SMS

class LogObserver(Observer):
def update(self, subject: Subject):
print(f" LogObserver: Logging state change to {[Link]}")
# Registra log

# Uso
subject = Subject()

# Registra observers
email_obs = EmailObserver()
sms_obs = SMSObserver()
log_obs = LogObserver()

[Link](email_obs)
[Link](sms_obs)
[Link](log_obs)

# Muda estado todos são notificados!


[Link] = "Order Created"
# EmailObserver: State changed to Order Created
# SMSObserver: State changed to Order Created
# LogObserver: Logging state change to Order Created

[Link] = "Payment Processed"


# Todos notificados novamente!

# EXEMPLO PRÁTICO: Event Bus

class EventBus:
"""Event bus simples usando Observer."""

def __init__(self):
self._subscribers = {}

def subscribe(self, event_type: str, callback: callable):


"""Registra callback para tipo de evento."""
if event_type not in self._subscribers:
self._subscribers[event_type] = []
self._subscribers[event_type].append(callback)

def publish(self, event_type: str, data: dict):


"""Publica evento."""
if event_type in self._subscribers:
for callback in self._subscribers[event_type]:
callback(data)

# Uso
event_bus = EventBus()

def send_welcome_email(data):
print(f"Sending welcome email to {data['email']}")

def create_user_profile(data):
print(f"Creating profile for {data['user_id']}")

def log_user_registration(data):
print(f"Logging registration: {data}")

# Registra handlers
event_bus.subscribe("user_registered", send_welcome_email)
event_bus.subscribe("user_registered", create_user_profile)
event_bus.subscribe("user_registered", log_user_registration)
# Publica evento todos handlers executam
event_bus.publish("user_registered", {
"user_id": "123",
"email": "user@[Link]"
})
3.3) Command
"""
COMMAND: Encapsula requisição como objeto.

Quando usar:
Undo/Redo
Queue de comandos
Transações
Macro recording
"""

from abc import ABC, abstractmethod


from typing import List

# Command interface
class Command(ABC):
@abstractmethod
def execute(self):
pass

@abstractmethod
def undo(self):
pass

# Receiver
class TextEditor:
"""Receiver: objeto que executa ação."""

def __init__(self):
[Link] = ""

def insert(self, text: str, position: int):


[Link] = [Link][:position] + text + [Link][position:]

def delete(self, position: int, length: int):


[Link] = [Link][:position] + [Link][position + length:]

def __str__(self):
return [Link]

# Concrete Commands
class InsertCommand(Command):
def __init__(self, editor: TextEditor, text: str, position: int):
[Link] = editor
[Link] = text
[Link] = position
def execute(self):
[Link]([Link], [Link])

def undo(self):
[Link]([Link], len([Link]))

class DeleteCommand(Command):
def __init__(self, editor: TextEditor, position: int, length: int):
[Link] = editor
[Link] = position
[Link] = length
self.deleted_text = ""

def execute(self):
# Salva texto deletado para undo
self.deleted_text = [Link][
[Link]:[Link] + [Link]
]
[Link]([Link], [Link])

def undo(self):
[Link](self.deleted_text, [Link])

# Invoker
class CommandHistory:
"""Invoker: gerencia execução e histórico."""

def __init__(self):
[Link]: List[Command] = []
[Link] = -1

def execute(self, command: Command):


"""Executa comando e adiciona ao histórico."""
# Remove comandos após current (se houve undo)
[Link] = [Link][:[Link] + 1]

[Link]()
[Link](command)
[Link] += 1

def undo(self):
"""Desfaz último comando."""
if [Link] >= 0:
[Link][[Link]].undo()
[Link] -= 1

def redo(self):
"""Refaz comando desfeito."""
if [Link] < len([Link]) - 1:
[Link] += 1
[Link][[Link]].execute()

# Uso
editor = TextEditor()
history = CommandHistory()

# Executar comandos
[Link](InsertCommand(editor, "Hello", 0))
print(editor) # Hello

[Link](InsertCommand(editor, " World", 5))


print(editor) # Hello World

[Link](InsertCommand(editor, "!", 11))


print(editor) # Hello World!

# Undo
[Link]()
print(editor) # Hello World

[Link]()
print(editor) # Hello

# Redo
[Link]()
print(editor) # Hello World

4. PADRÕES ARQUITETURAIS
4.1) Repository Pattern
"""
REPOSITORY: Abstração para acesso a dados.

Benefícios:
Desacopla domínio de infraestrutura
Facilita testes
Centraliza lógica de queries
"""

from abc import ABC, abstractmethod

class UserRepository(ABC):
"""Interface do repositório."""

@abstractmethod
def save(self, user: User) -> None:
pass

@abstractmethod
def find_by_id(self, user_id: str) -> User | None:
pass

@abstractmethod
def find_by_email(self, email: str) -> User | None:
pass

# Implementação em memória (testes)


class InMemoryUserRepository(UserRepository):
def __init__(self):
[Link] = {}

def save(self, user: User) -> None:


[Link][[Link]] = user

def find_by_id(self, user_id: str) -> User | None:


return [Link](user_id)

def find_by_email(self, email: str) -> User | None:


for user in [Link]():
if [Link] == email:
return user
return None

# Implementação com SQLAlchemy (produção)


class SQLAlchemyUserRepository(UserRepository):
def __init__(self, session):
[Link] = session

def save(self, user: User) -> None:


orm_user = UserORM.from_domain(user)
[Link](orm_user)
[Link]()

def find_by_id(self, user_id: str) -> User | None:


orm_user = [Link](UserORM).get(user_id)
return orm_user.to_domain() if orm_user else None
4.2) Unit of Work
"""
UNIT OF WORK: Mantém lista de objetos modificados e coordena escrita.

Benefícios:
Transações consistentes
Minimiza acessos ao banco
Gerencia dependências entre objetos
"""

class UnitOfWork:
"""Unit of Work pattern."""

def __init__(self, session):


[Link] = session
[Link] = SQLAlchemyUserRepository(session)
[Link] = SQLAlchemyOrderRepository(session)

def __enter__(self):
return self

def __exit__(self, exc_type, exc_val, exc_tb):


if exc_type is None:
[Link]()
else:
[Link]()

def commit(self):
"""Commit de todas mudanças."""
[Link]()

def rollback(self):
"""Rollback de todas mudanças."""
[Link]()

# Uso
with UnitOfWork(session) as uow:
# Múltiplas operações na mesma transação
user = [Link].find_by_id("123")
user.update_email("new@[Link]")
[Link](user)

order = [Link](user_id=[Link])
[Link](order)

# Commit automático ao sair do with (se sem exceção)

5. ANTI-PATTERNS
5.1) God Object
# ANTI-PATTERN: God Object

class OrderManager:
"""Faz TUDO relacionado a pedidos (ruim!)."""

def create_order(self, ...):


# Valida dados
# Verifica estoque
# Processa pagamento
# Envia email
# Atualiza analytics
# Gera relatório
# ...
pass

def cancel_order(self, ...):


pass
def calculate_shipping(self, ...):
pass

def send_notification(self, ...):


pass

def generate_invoice(self, ...):


pass

# 50+ métodos...

# SOLUÇÃO: Single Responsibility

class OrderService:
def __init__(
self,
inventory_service,
payment_service,
notification_service
):
[Link] = inventory_service
[Link] = payment_service
[Link] = notification_service

def create_order(self, ...):


# Coordena serviços especializados
[Link](...)
[Link](...)
[Link](...)
5.2) Spaghetti Code
# ANTI-PATTERN: Spaghetti Code

def process_order(order_data):
# Validação misturada com lógica de negócio
if not order_data.get("customer_id"):
return {"error": "No customer"}

# Acesso direto ao banco


customer = [Link](f"SELECT * FROM customers WHERE id={order_data['customer_id']}")

# Lógica complexa sem estrutura


total = 0
for item in order_data["items"]:
product = [Link](f"SELECT * FROM products WHERE id={item['id']}")
if product["stock"] < item["qty"]:
return {"error": "Out of stock"}
total += product["price"] * item["qty"]

# Chamada HTTP misturada


payment = [Link]("[Link] json={"amount": total})

# ... mais 200 linhas assim


# SOLUÇÃO: Separação de responsabilidades

class CreateOrderUseCase:
def __init__(self, order_repo, inventory_service, payment_service):
self.order_repo = order_repo
[Link] = inventory_service
[Link] = payment_service

def execute(self, request: CreateOrderRequest) -> CreateOrderResponse:


# Validação
self._validate(request)

# Lógica de negócio separada


order = [Link](...)

# Serviços especializados
[Link]([Link])
[Link]([Link])

# Persistência
self.order_repo.save(order)

return CreateOrderResponse(order_id=[Link])

📚 RECURSOS ADICIONAIS
Livro Clássico:

"Design Patterns: Elements of Reusable Object-Oriented Software" - Gang of Four (1994)

Livros Modernos:

"Head First Design Patterns" - Freeman & Freeman


"Refactoring to Patterns" - Joshua Kerievsky

Sites:

[Link]: [Link]
Source Making: [Link]

You might also like