Módulo 15 - Empacotamento e boas práticas

Padrões pythônicos e código limpo

10 min de leitura · por Cesar Gargiulo, revisado pela equipe ValorFinal e GuardiaSec · Atualizado em 01/07/2026

O que você vai aprender

  • Implementar o padrão estratégia usando funções em vez de classes.
  • Escrever uma fábrica simples que cria objetos conforme a entrada.
  • Aplicar nomes claros e funções pequenas como base do código limpo.
  • Reconhecer e evitar repetição com o princípio DRY.

Padrão estratégia com uma função

Em muitas linguagens, escolher um algoritmo em tempo de execução exige o padrão estratégia com várias classes: uma interface e uma classe para cada variação. Em Python, isso costuma ser exagero, porque funções são objetos de primeira classe: você pode guardar uma função numa variável, colocá-la num dicionário e passá-la como argumento. O padrão estratégia então se resume a escolher qual função usar. O resultado é um código muito mais enxuto, que faz o mesmo trabalho sem a cerimônia de uma hierarquia de classes.

def frete_normal(peso: float) -> float:
    return peso * 2.0

def frete_expresso(peso: float) -> float:
    return peso * 2.0 + 15.0

def frete_gratis(peso: float) -> float:
    return 0.0

# A "estrategia" e apenas a funcao escolhida
def calcular_frete(peso: float, estrategia) -> float:
    return estrategia(peso)

print(calcular_frete(10, frete_expresso))   # 35.0

# Um dicionario mapeia nome para estrategia, sem cadeia de if
estrategias = {"normal": frete_normal, "expresso": frete_expresso, "gratis": frete_gratis}
escolha = "gratis"
print(calcular_frete(10, estrategias[escolha]))   # 0.0

O padrão estratégia em Python: passar a função e mapear nomes para funções num dicionário.

O dicionário de estratégias merece atenção, porque substitui com elegância uma cadeia de if e elif. Em vez de comparar o nome da escolha num monte de condicionais, você mapeia cada nome para a função correspondente e busca direto. Adicionar uma estratégia nova é acrescentar uma entrada no dicionário, sem tocar na função calcular_frete. É o princípio aberto-fechado da aula anterior aparecendo de novo, agora no estilo enxuto e funcional que o Python favorece.

Uma fábrica simples

Outro padrão clássico que fica leve em Python é a fábrica, uma função cujo trabalho é criar e devolver o objeto certo conforme a entrada, escondendo de quem chama os detalhes de qual classe instanciar. Ela centraliza a decisão de criação num só lugar. Se amanhã surgir um tipo novo, você mexe apenas na fábrica, e todo o resto do código, que só pede um objeto à fábrica, continua igual. É uma aplicação direta de responsabilidade única, com a criação isolada do uso.

from abc import ABC, abstractmethod

class Notificador(ABC):
    @abstractmethod
    def enviar(self, mensagem: str) -> None: ...

class NotificadorEmail(Notificador):
    def enviar(self, mensagem: str) -> None:
        print(f"e-mail: {mensagem}")

class NotificadorSMS(Notificador):
    def enviar(self, mensagem: str) -> None:
        print(f"sms: {mensagem}")

# Fabrica: decide qual objeto criar; quem chama nao precisa saber
def criar_notificador(canal: str) -> Notificador:
    tipos = {"email": NotificadorEmail, "sms": NotificadorSMS}
    if canal not in tipos:
        raise ValueError(f"canal desconhecido: {canal}")
    return tipos[canal]()

n = criar_notificador("sms")
n.enviar("seu pedido foi enviado")   # sms: seu pedido foi enviado

A fábrica criar_notificador concentra a decisão de qual classe instanciar num único lugar.

Código limpo: o alicerce de tudo

Nenhum padrão salva um código de nomes ruins e funções gigantes. O código limpo é o alicerce, e ele começa nos nomes. Um nome deve dizer o que a coisa é ou faz, sem exigir um comentário: calcular_frete é melhor que cf, quantidade_itens é melhor que qi. Em seguida vêm as funções pequenas, que fazem uma coisa só e cabem na tela; quando uma função cresce demais e ganha vários blocos com comentários explicando cada trecho, é sinal de que ela quer virar várias funções. Código limpo não é enfeite; é o que permite ler, entender e mudar sem medo.

Código que dá trabalho

  • Nomes curtos e enigmáticos (x, tmp, d1)
  • Funções longas que fazem tudo
  • Mesma lógica copiada em vários lugares
  • Comentários explicando código confuso

Código limpo

  • Nomes que dizem a intenção
  • Funções pequenas, uma responsabilidade cada
  • Lógica em um lugar só, reaproveitada (DRY)
  • Código claro o bastante para dispensar comentário

O terceiro pilar é o princípio DRY, não se repita. Quando a mesma lógica aparece copiada em três lugares, uma correção precisa ser feita três vezes, e um dia você esquece uma delas: nasce o bug. Extraia a lógica repetida para uma função com um bom nome e chame-a nos três lugares. Agora a mudança acontece num ponto só. Um cuidado honesto: DRY é sobre não duplicar conhecimento, não sobre eliminar toda linha parecida a qualquer custo. Forçar a fusão de trechos que só por acaso se parecem cria acoplamento ruim. O bom senso, como sempre, decide.

Com este módulo você fecha o lado de engenharia do curso. Já sabe estruturar um projeto em pacotes, declará-lo no pyproject.toml, resolver imports, manter o estilo com PEP 8 e ferramentas, aplicar os princípios de SOLID com moderação e escrever código limpo e pythônico. É exatamente esse conjunto que separa quem faz scripts que funcionam de quem constrói software que uma equipe mantém por anos. No próximo e último módulo, tudo isso vira prática: você projeta e constrói uma mini biblioteca completa.

Teste rápido

O que o princípio DRY recomenda?

Perguntas frequentes

Por que o padrão estratégia é mais simples em Python?
Porque funções são objetos de primeira classe: você pode guardá-las em variáveis, dicionários e passá-las como argumento. Isso dispensa a hierarquia de classes que outras linguagens exigem para o padrão estratégia. Muitas vezes, a estratégia é só a função certa passada adiante.
Quando vale a pena usar uma fábrica?
Quando a decisão de qual objeto criar se repete pelo código ou tende a mudar. Centralizar a criação numa fábrica concentra essa lógica num lugar só, de modo que adicionar um tipo novo mexe apenas na fábrica. Para um único ponto de criação simples, a fábrica pode ser exagero.
Qual é o maior fator de código limpo?
Os nomes. Um nome que revela a intenção elimina a necessidade de comentário e torna o código autoexplicativo. Depois vêm as funções pequenas, com uma responsabilidade cada, e a ausência de duplicação. Nomes bons sozinhos já melhoram a legibilidade de forma impressionante.
DRY significa que nunca posso ter código parecido?
Não. DRY é sobre não duplicar conhecimento, não sobre eliminar toda semelhança superficial. Dois trechos que se parecem por acaso, mas mudam por motivos diferentes, devem ficar separados. Forçar a fusão deles cria acoplamento ruim. Unifique quando os trechos representam a mesma regra de fato.
Preciso decorar todos os padrões de projeto clássicos?
Não. Vale conhecer alguns, como estratégia e fábrica, porque eles nomeiam soluções recorrentes. Mas em Python muitos ficam simples ou desnecessários. Mais importante que decorar catálogos de padrões é dominar código limpo e os princípios que os padrões, no fundo, tentam alcançar.

Fontes

Seu progresso fica salvo neste aparelho. Assinantes sincronizam entre os aparelhos.