Design Patterns para Back-end | [SIS]ANO2C2B2S8A2
[ SIS ] ANO2C2B2S8A2·Unidade 2 · Componente 2 · Aula 8.2·Ensino Médio Técnico — Desenvolvimento de Sistemas

Singleton, Factory Method, Circuit Breaker e Service Registry — os padrões que toda equipe de desenvolvimento precisa dominar antes de colocar qualquer sistema em produção.

PythonBack-end Design PatternsCircuit Breaker SEDUC-SP

Por que código bem escrito ainda pode ser um pesadelo de manutenção?

Você pode escrever código sintaticamente correto, com variáveis bem nomeadas, sem bugs aparentes — e ainda assim criar um sistema que nenhum desenvolvedor quer tocar seis meses depois. O problema não está na sintaxe. Está na estrutura. Design patterns existem precisamente para resolver isso: são soluções consolidadas para problemas recorrentes de estruturação de código que toda equipe enfrenta, independentemente de linguagem ou porte do projeto.

Na aula anterior ([SIS]ANO2C2B2S8A1), comparamos arquitetura monolítica e microsserviços. Agora a pergunta muda: dado que você escolheu sua arquitetura, como organiza o código dentro dela? É aí que os padrões de design entram — não como regras obrigatórias, mas como vocabulário compartilhado que torna decisões de design comunicáveis e replicáveis.

Custo concreto de ignorar padrões: sem design patterns, cada desenvolvedor resolve o mesmo problema de forma diferente. O resultado é um codebase onde ninguém entende o raciocínio por trás de cada decisão, a curva de onboarding é enorme e qualquer mudança gera efeitos colaterais imprevisíveis.

Como ensinar design patterns no ensino médio técnico sem perder a objetividade?

A aula [SIS]ANO2C2B2S8A2 resolve um problema didático real: padrões de design têm reputação de abstratos e difíceis de contextualizar. A estratégia da SEDUC-SP é eficiente — um sistema de e-commerce como âncora narrativa, passando do monolito para microsserviços em Python executável no Google Colab. O estudante não aprende um padrão no vácuo: aprende quando e por que aplicá-lo num problema que já conhece.

≡ definição · design pattern

Solução reutilizável e nomeada para um problema recorrente de design de software. Não é código pronto — é um modelo estrutural que descreve como organizar classes e objetos para resolver uma categoria de problema de forma eficiente e manutenível.

Quais design patterns se aplicam a cada arquitetura?

PADRÃOARQUITETURAPROBLEMA QUE RESOLVECONTEXTO
SingletonMonolíticaGarantir uma única instância de uma classe em toda a aplicaçãoConexão com BD, configurações globais, logger
Factory MethodMonolíticaDelegar criação de objetos a subclasses sem especificar a classe concretaCriação de usuários por perfil, relatórios por tipo
Service RegistryMicrosserviçosGerenciar localização dinâmica de serviços em ambientes distribuídosService discovery em nuvem, load balancing
Circuit BreakerMicrosserviçosEvitar falhas em cascata ao isolar serviços instáveisResiliência em chamadas entre microsserviços

Padrões para arquitetura monolítica

padrão criacional · monolito

Singleton

Restringe a instanciação a um único objeto. Essencial quando um recurso compartilhado — conexão de banco, pool de threads — não pode ter múltiplas instâncias concorrentes sem custo catastrófico.

padrão criacional · monolito

Factory Method

Define uma interface para criar objetos, mas deixa subclasses decidirem qual classe instanciar. Separa criação de uso — fundamental para sistemas que evoluem com novos tipos de objeto.

Padrões para arquitetura de microsserviços

padrão estrutural · microsserviços

Service Registry

Mantém catálogo atualizado dos serviços e seus endereços. Sem ele, endpoints ficam hardcoded — inviabilizando escala dinâmica e deploy independente. Ferramentas: Consul, Eureka, etcd.

padrão de resiliência · microsserviços

Circuit Breaker

Três estados: fechado (normal), aberto (bloqueado após falhas), meio-aberto (testando recuperação). Evita que uma falha isolada cascateie pelo sistema inteiro.

Como implementar a transição monolito → microsserviços em Python?

Passo 1 — Sistema monolítico

ecommerce_monolito.py
# Arquitetura Monolítica — todas as responsabilidades em uma única classe
class EcommerceSystem:
    def __init__(self):
        self.users = []; self.products = []; self.orders = []

    def add_user(self, user): self.users.append(user)
    def add_product(self, product): self.products.append(product)

    def place_order(self, user, product):
        if product in self.products:
            self.orders.append((user, product))
            return "Order placed successfully"
        return "Product not available"

system = EcommerceSystem()
system.add_user("Alice"); system.add_product("Laptop")
print(system.place_order("Alice", "Laptop"))  # Order placed successfully

Passo 2 — Refatoração para microsserviços com injeção de dependência

ecommerce_microsservicos.py
# Microsserviços — cada classe com responsabilidade única e bem definida
class UserService:
    def __init__(self): self.users = []
    def add_user(self, user): self.users.append(user)

class ProductService:
    def __init__(self): self.products = []
    def add_product(self, product): self.products.append(product)
    def check_availability(self, product):
        return product in self.products  # contrato de interface público

class OrderService:
    def __init__(self): self.orders = []
    def place_order(self, user, product, product_service):
        # injeção de dependência — recebe serviço externo como parâmetro
        if product_service.check_availability(product):
            self.orders.append((user, product))
            return "Order placed successfully"
        return "Product not available"

user_svc = UserService(); prod_svc = ProductService(); ord_svc = OrderService()
user_svc.add_user("Alice"); prod_svc.add_product("Laptop")
print(ord_svc.place_order("Alice", "Laptop", prod_svc))  # Output idêntico
O que mudou estruturalmente: o output é idêntico — mas a estrutura é completamente diferente. OrderService não sabe nada sobre a implementação interna do ProductService — só sabe que ele tem o método check_availability(). Isso é o princípio aberto/fechado (Open/Closed) aplicado na prática: OrderService pode ser estendido sem ser modificado.

Como os padrões de design aparecem em uma atividade prática real?

! caso real · roteiro de aula prática — grupos de 4 pessoas · 45 minutos

Construindo e refatorando um e-commerce em três fases

  • Fase 1 — monolito: implementar EcommerceSystem completo. Executar e validar output. Identificar onde estão os gargalos de manutenção.
  • Fase 2 — refatoração: extrair para UserService, ProductService e OrderService. Aplicar injeção de dependência. Output deve ser idêntico.
  • Fase 3 — análise: adicionar PaymentService nas duas versões. Comparar: qual versão exige mais mudanças? Como os padrões de design explicam essa diferença?
→ expansão estratégica · 4 frentes

De aula de design patterns a ativo pedagógico e intelectual

{ }Curso Técnico

Evoluir o e-commerce para API REST com Flask — cada serviço vira um Blueprint separado. Conectar com a aula de segurança para autenticação por serviço.

Blog / Autoridade

Série “Padrões que todo dev júnior precisa conhecer” — artigos curtos com exemplos em Python para o mercado de São Paulo.

[ ]Cultura Maker

Alunos identificam padrões usados em apps do cotidiano (iFood, Instagram) e constroem um mini-clone aplicando Singleton e Factory Method.

>_Formação Docente

Oficina: como ensinar design patterns sem infraestrutura complexa, usando apenas Google Colab e cenários reais de e-commerce.

Síntese: design patterns não são regras impostas — são soluções que equipes inteligentes descobriram de forma independente e que a comunidade consolidou em nomes e estruturas reutilizáveis. Conhecê-los é aprender o vocabulário da engenharia de software.

Perguntas frequentes sobre design patterns

O que são design patterns no desenvolvimento de software?
Design patterns são soluções reutilizáveis para problemas recorrentes no design de software. Não são código pronto — são modelos conceituais que descrevem como estruturar classes e objetos para resolver categorias de problema de forma eficiente e manutenível.
Qual a diferença entre Singleton e Factory Method?
Singleton garante que uma classe tenha apenas uma instância em toda a aplicação, com um ponto global de acesso. Factory Method delega a criação de objetos a subclasses sem especificar a classe concreta. O primeiro controla instância; o segundo desacopla criação de uso.
O que é o padrão Circuit Breaker e por que é essencial em microsserviços?
Circuit Breaker monitora chamadas entre serviços e, ao detectar falhas repetidas, interrompe temporariamente a comunicação — evitando falhas em cascata. É essencial porque uma falha em um único serviço pode se propagar por toda a cadeia de dependências.
Quando usar Service Registry em uma arquitetura de microsserviços?
Service Registry é necessário quando múltiplos serviços precisam se localizar dinamicamente em tempo de execução. Sem ele, os endereços ficam hardcoded — inviabilizando escala e deploy independente. Ferramentas como Consul, Eureka e etcd implementam esse padrão.
É possível aplicar design patterns no ensino médio técnico sem infraestrutura complexa?
Sim. Classes Python com responsabilidade única representam o princípio de separação de serviços. Singleton pode ser implementado com um atributo de classe. Circuit Breaker pode ser simulado com um contador de falhas. O Google Colab elimina a necessidade de instalação de ambiente local.

Acesse todos os materiais do Curso Técnico

Roteiros de aula prática, slides, projetos maker e reflexões sobre IA na escola pública.

→ professorcomia.com.br

Design patterns como mentalidade, não como memorização

A habilidade real não está em saber o nome de 23 padrões do livro Gang of Four — está em reconhecer, diante de um problema de código, que aquele problema já foi resolvido antes, de forma elegante, e que existe um vocabulário para comunicar essa solução ao time. Isso é o que separa o desenvolvedor que escreve código que funciona do engenheiro que projeta sistemas que duram.

// código da aula: [SIS]ANO2C2B2S8A2 · unidade 2 · componente 2 · aula 8.2
// design patterns para back-end · seduc-sp · curso técnico desenvolvimento de sistemas
// publicado em: professorcomia.com.br · diariodeumpoed.com.br · poed · 2024

>_ slides da aula

[SIS]ANO2C2B2S8A2 · design patterns para back-end · 2º ano · aula 8.2

slide 01
abertura

>_ Arquitetura de Aplicações Back-end — Aula 8.2

FREQUÊNCIA — registre sua presença no AVA antes de iniciar
  • Código: [SIS]ANO2C2B2S8A2 — Unidade 2 · Componente 2
  • Na aula anterior: escolhemos entre monolito e microsserviços — agora vamos aprender como estruturar o código dentro de cada arquitetura
  • Tema da semana: aplicar os melhores design patterns para garantir escalabilidade
? pergunta provocadora — antes de qualquer slide Você já leu um código escrito por outra pessoa e não entendeu nada — mesmo sem erros de sintaxe? O que tornaria esse código mais fácil de entender sem mudar o que ele faz?
slide 02
objetivos

[ ] O que vamos construir hoje

conceitual

Identificar Singleton, Factory Method, Service Registry e Circuit Breaker — e os contextos de uso de cada um em monolito e microsserviços.

procedimental

Implementar em Python um e-commerce monolítico e refatorá-lo para microsserviços aplicando os padrões estudados.

atitudinal

Desenvolver senso crítico para avaliar quando cada padrão é — ou não é — a melhor escolha para um problema específico.

≡ recursos · computador · Google Colab (colab.research.google.com) · caderno · roteiro da aula prática
slide 03
problema_gerador

! Código que funciona — mas ninguém quer manter

cenário monolito

Um e-commerce com usuários, produtos e pedidos em uma única classe. Funciona perfeitamente. Mas adicionar desconto no pedido quebra o cadastro de produtos. Ninguém sabe exatamente por quê.

cenário microsserviços

Serviços separados — mas o OrderService chama o ProductService via rede. Se o ProductService cair 3 vezes em 1 minuto, todos os pedidos em andamento travam. O sistema inteiro para.

? 5 minutos — no caderno, antes de codificar Que “regras de organização” você já aplica no seu código sem saber que são padrões? (ex: uma função = uma tarefa, nunca repetir a mesma lógica) Anote pelo menos duas e compartilhe com o grupo.
slide 04
conceito

O que são Design Patterns?

  • Definição precisa: soluções reutilizáveis e nomeadas para problemas recorrentes de estruturação de código — não são código para copiar, são modelos
  • Por que nomes importam: “vamos usar um Singleton aqui” comunica em uma frase o que levaria um parágrafo — vocabulário compartilhado que reduz retrabalho
  • Origem: “Design Patterns” (Gang of Four, 1994) — 23 padrões: criacionais, estruturais e comportamentais
  • Fato crítico: padrões descrevem relações entre classes — não entre linhas de código
01

Se design patterns existem desde 1994, por que ainda vemos código “sem padrão” em produção? É falta de conhecimento ou falta de disciplina? São a mesma coisa?

02

Um time de 2 devs num projeto de 3 meses precisa de design patterns? A partir de qual escala eles se tornam obrigatórios? Quem decide — o dev, o time ou o cliente?

slide 05
conceito

# Padrões para Arquitetura Monolítica monolito

  • Singleton: uma única instância de uma classe em toda a aplicação — conexão com BD, configurações globais, logger centralizado
  • Factory Method: delega criação de objetos a subclasses sem especificar a classe concreta — desacopla criação de uso
  • Onde você já viu: db.connect() chamado uma única vez no app inteiro = Singleton. Criar objetos User diferentes por perfil = Factory Method
singleton_conceito.py▶ Colab
# Singleton: _instance bloqueia criação de múltiplos objetos
class DatabaseConnection:
    _instance = None
    def __new__(cls):
        if not cls._instance:
            cls._instance = super().__new__(cls)
        return cls._instance
01

O que acontece se não usar Singleton para conexão com banco e cada request criar uma nova conexão? Qual o risco real em produção com 10.000 usuários simultâneos?

slide 06
conceito

Padrões para Microsserviços microservices

  • Service Registry: catálogo dinâmico de serviços e endereços — sem ele, qualquer deploy exige atualização manual de configurações em todos os dependentes
  • Circuit Breaker: fechadoaberto (falhas detectadas, tráfego bloqueado) → meio-aberto (teste de recuperação automática)
  • Por que Circuit Breaker é crítico: um serviço lento congela todos os que dependem dele — efeito dominó que pode derrubar sistemas inteiros
01

No iFood: se o serviço de pagamento cair, pedidos confirmados devem ser cancelados automaticamente? O Circuit Breaker deve abrir imediatamente ou aguardar 3 falhas? Qual a decisão de negócio por trás disso?

02

Service Registry resolve problema de infraestrutura ou de código? Você consegue imaginar microsserviços em produção sem ele funcionando por mais de um mês?

slide 07
caderno

Glossário — Design Patterns desta aula

  • Design Pattern solução nomeada e reutilizável para problema recorrente de estrutura de código
  • Singleton garante uma única instância de uma classe via atributo _instance
  • Factory Method delega criação de objetos a subclasses, desacoplando criação de uso
  • Service Registry catálogo dinâmico de serviços e endereços em arquitetura distribuída
  • Circuit Breaker interrompe comunicação com serviços instáveis para evitar falhas em cascata
  • check_availability() contrato de interface do ProductService — retorna True/False sem expor implementação interna
? escreva no caderno antes de avançar
  • Qual desses padrões você já usou sem saber o nome? Dê um exemplo do seu próprio código ou de um app que você usa diariamente.
  • A classe EcommerceSystem (monolito) viola qual princípio que os padrões tentam resolver?
slide 08
pause_e_responda · 1 de 3

? Pause e Responda — Questão 1

Qual é a principal característica da arquitetura monolítica?
  • A Tudo está integrado em um único bloco de código.
  • B Escalabilidade fácil e independente.
  • C Cada funcionalidade é um serviço independente.
  • D Comunicação entre serviços via API.

// escreva sua resposta no caderno · depois registre no AVA

slide 09
gabarito · questão 1

Gabarito — Questão 1

Qual é a principal característica da arquitetura monolítica?
  • A Tudo está integrado em um único bloco de código.
  • B Escalabilidade fácil e independente. → característica de microsserviços, não do monolito
  • C Cada funcionalidade é um serviço independente. → definição exata de microsserviço
  • D Comunicação entre serviços via API. → padrão de arquitetura distribuída

✓ Na arquitetura monolítica todos os componentes estão em um único bloco — facilita o desenvolvimento inicial mas limita escalabilidade e manutenção a longo prazo.

slide 10
pause_e_responda · 2 de 3

? Pause e Responda — Questão 2

Qual é um dos principais desafios ao migrar para uma arquitetura de microsserviços?
  • A Garantir a comunicação eficiente entre serviços.
  • B Eliminar a necessidade de escalar serviços individualmente.
  • C Reduzir a complexidade do sistema.
  • D Manter a aplicação em um único bloco de código.

// escreva sua resposta no caderno · depois registre no AVA

slide 11
gabarito · questão 2

Gabarito — Questão 2

Qual é um dos principais desafios ao migrar para uma arquitetura de microsserviços?
  • A Garantir a comunicação eficiente entre serviços.
  • B Eliminar a necessidade de escalar serviços individualmente. → escala independente é vantagem, não desafio
  • C Reduzir a complexidade do sistema. → microsserviços aumentam complexidade operacional
  • D Manter a aplicação em um único bloco de código. → desafio do monolito — oposto dos microsserviços

✓ A natureza distribuída exige comunicação via rede — com latência, falhas e necessidade de Circuit Breaker e Service Registry para garantir resiliência.

slide 12
pause_e_responda · 3 de 3

? Pause e Responda — Questão 3

Qual padrão de design é comumente usado para garantir a resiliência em uma arquitetura de microsserviços?
  • A Factory Method
  • B Circuit Breaker
  • C Observer
  • D Singleton

// tempo total do quiz: 3 minutos · registre no AVA após responder no caderno

slide 13
gabarito · questão 3

Gabarito — Questão 3

Qual padrão de design é comumente usado para garantir a resiliência em uma arquitetura de microsserviços?
  • A Factory Method → padrão criacional — cria objetos, não garante resiliência de rede
  • B Circuit Breaker
  • C Observer → padrão comportamental — notificações entre componentes, não resiliência
  • D Singleton → padrão criacional — controla instâncias, mais usado em monolitos

✓ Circuit Breaker “quebra o circuito” ao detectar falhas repetidas — evita que uma falha isolada se propague por toda a cadeia de microsserviços dependentes.

slide 14
contexto_atividade · aula prática

{ } Aula Prática — E-commerce: monolito → microsserviços

  • Cenário: construir em Python um e-commerce monolítico e refatorar para microsserviços aplicando os padrões estudados
  • Objetivo: observar como a refatoração afeta manutenção, flexibilidade e escalabilidade do código na prática
  • Formato: grupos de 4 pessoas · 45 minutos · roteiro impresso ou digital
  • Ferramenta: Google Colab — acesso pelo navegador, sem instalação local necessária
01

Antes de abrir o Colab: qual parte do e-commerce você espera ser mais difícil de refatorar? Escreva sua previsão e confira ao final — sua intuição estava certa?

02

O output das duas versões será idêntico. Se o resultado é o mesmo, por que a refatoração vale 45 minutos de trabalho? Quem ganha quando o código é “mais bonito”?

slide 15
planejamento

Planejamento — estrutura antes do código

Antes de digitar, esboce no papel. Quais classes? Quais métodos? Quem depende de quem? Qual o fluxo dos dados?

SERVIÇO / CLASSERESPONSABILIDADEMÉTODO PRINCIPALDEPENDE DE
EcommerceSystemTudo centralizado (monolito)place_order(user, product)
UserServiceGerenciar usuáriosadd_user(user)
ProductServiceGerenciar produtoscheck_availability(product)
OrderServiceProcessar pedidosplace_order(user, product, svc)ProductService
? antes de codificar — responda no caderno Por que OrderService.place_order recebe product_service como parâmetro em vez de criá-lo internamente? Que padrão de design esse comportamento representa?
slide 16
algoritmo

>_ Fluxo lógico — os 3 passos do roteiro

  • Passo 1 — Monolito: implementar EcommerceSystem com add_user, add_product e place_order em uma única classe
  • Passo 2 — Microsserviços: extrair para 3 classes independentes; OrderService.place_order recebe product_service via injeção de dependência
  • Passo 3 — Análise: executar as duas versões, comparar estrutura e adicionar PaymentService — observar qual versão é mais fácil de estender
linha crítica — Passo 2 (injeção de dependência)
def place_order(self, user, product, product_service):
    if product_service.check_availability(product):
        self.orders.append((user, product))
        return "Order placed successfully"
    return "Product not available"
slide 17
implementacao

Implementação — Google Colab, passo a passo

  • Acesse: colab.research.google.com → Novo notebook → renomeie para design_patterns.ipynb
  • Célula 1: cole e execute o código do Passo 1 — verifique o output esperado antes de avançar
  • Célula 2: cole e execute o código do Passo 2 (3 serviços) — output deve ser idêntico à Célula 1
  • Célula 3: adicione PaymentService à versão microsserviços — observe quais classes mudam e quais permanecem intactas
01

Ao adicionar PaymentService: no monolito você precisa modificar EcommerceSystem. Nos microsserviços, apenas OrderService muda. Isso é coincidência ou consequência direta dos padrões aplicados?

slide 18
testes

! Testes — 3 casos obrigatórios por versão

caso normal

Usuário válido · produto cadastrado · pedido realizado normalmente

→ “Order placed successfully”

caso limite

Produto não cadastrado no catálogo · pedido tentado

→ “Product not available”

extensão

Adicionar PaymentService nas duas versões — quais classes mudam?

→ verificar isolamento real

? análise final do grupo — escreva antes de entregar Na versão monolítica, adicionar PaymentService exige alterar EcommerceSystem. Na versão microsserviços, apenas OrderService muda. O que esse comportamento revela sobre qual arquitetura facilita manutenção — e como os padrões de design explicam isso?
slide 19
entrega_ava

Entrega — O que enviar no AVA

o que enviar
  • Roteiro da aula prática preenchido (nome + turma)
  • Link ou print do notebook Colab com os 3 passos
  • Respostas escritas às 3 perguntas de reflexão do roteiro
  • Print do output dos 3 casos de teste
critérios de avaliação
  • Código funcional — output correto nas duas versões
  • Refatoração correta — 3 classes com responsabilidade única
  • Reflexão fundamentada nas 3 perguntas finais do roteiro
  • Participação ativa durante a atividade em grupo
⌨ entrega · roteiro preenchido + notebook Colab + respostas de reflexão · AVA · prazo: conforme calendário da turma
slide 20
síntese

Então ficamos assim…

Padrões p/ Monolito

Singleton e Factory Method organizam criação e acesso a objetos — mais controle, menos acoplamento em sistemas centralizados.

Padrões p/ Microsserviços

Circuit Breaker e Service Registry garantem resiliência e descoberta de serviços em arquiteturas distribuídas — essenciais em produção.

>_Python como laboratório

A refatoração monolito → microsserviços revela como padrões de design afetam manutenção, extensibilidade e separação de responsabilidades.

← aula anterior

Arquitetura monolítica vs. microsserviços — características, tradeoffs e representação em Python com classes simples.

→ próxima aula

Desenvolvimento de APIs — transformar serviços em endpoints REST acessíveis via HTTP usando Flask ou FastAPI.