O Princípio da Responsabilidade Única em Python: menos é mais

Em Python, é comum — especialmente pela flexibilidade da linguagem e pelo foco em produtividade — cairmos na armadilha de escrever grandes blocos de código em uma única função, método ou rota. Às vezes, é tentador resolver “tudo em um só lugar”: validar os dados, consultar o banco, tratar erros e ainda montar a resposta final.

Mas essa abordagem tem um preço. O código cresce, as responsabilidades se misturam e, de repente, você tem uma função que faz de tudo — e nada bem feito.

O que diz o Princípio da Responsabilidade Única (SRP)

Diretamente inspirado no primeiro princípio do SOLID, o SRP (“Single Responsibility Principle”) afirma que cada função, classe ou módulo deve ter apenas um motivo para mudar. Em outras palavras, cada unidade de código deve ter uma responsabilidade bem definida.

Isso melhora a legibilidade, reduz o acoplamento e torna o sistema muito mais fácil de evoluir.

Vamos ver um exemplo prático.

Exemplo: o anti-padrão

@app.route("/users", methods=["POST"])
def create_user():
    # 1. Validação
    data = request.json
    if "email" not in data:
        return {"error": "Email is required"}, 400

    # 2. Inserção no banco
    conn = sqlite3.connect("db.sqlite")
    cursor = conn.cursor()
    cursor.execute("INSERT INTO users (email) VALUES (?)", (data["email"],))
    conn.commit()
    conn.close()

    # 3. Notificação (simulada)
    send_welcome_email(data["email"])

    return {"message": "User created successfully"}, 201

Essa rota funciona, mas concentra três responsabilidades distintas: validação de dados, acesso ao banco e envio de e-mail. Isso viola o SRP.

Aplicando o princípio

Vamos refatorar o código, dividindo as responsabilidades:

def validate_user_data(data):
    if "email" not in data:
        raise ValueError("Email is required")

def save_user_to_db(email):
    conn = sqlite3.connect("db.sqlite")
    with conn:
        conn.execute("INSERT INTO users (email) VALUES (?)", (email,))
    return True

def send_notification(email):
    send_welcome_email(email)

@app.route("/users", methods=["POST"])
def create_user():
    try:
        data = request.json
        validate_user_data(data)
        save_user_to_db(data["email"])
        send_notification(data["email"])
        return {"message": "User created successfully"}, 201
    except ValueError as e:
        return {"error": str(e)}, 400

Agora a rota faz apenas o que deve: coordena o fluxo entre funções auxiliares. Cada função tem uma única responsabilidade clara e testável.

Por que isso é importante

Conclusão

Ao olhar para uma função, faça a si mesmo esta pergunta: “Quantas coisas ela faz?”. Se a resposta for mais de uma, é hora de quebrar o código em partes menores. O princípio da responsabilidade única não é apenas teórico — é uma forma prática de escrever código mais limpo, testável e confiável em Python.



Riverfount
Vicente Eduardo Ribeiro Marçal