Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Regla 0x2005h: Cada función debe tener una única responsabilidad (Principio de Responsabilidad Única)

Funciones, contratos y modularizacion (0x20XX)

Universidad Nacional de Río Negro

0x2005h: Cada función debe tener una única responsabilidad (Principio de Responsabilidad Única)

Enunciado normativo

DEBE poder describirse la responsabilidad de cada función con una sola frase sin conjunciones. Si la descripción necesita un “y” (o un “además”), la función DEBE dividirse en funciones separadas.

¿Por qué existe esta regla?

El problema

Una función con dos responsabilidades tiene dos motivos para cambiar y dos conjuntos de pruebas; el lector no puede reutilizar la mitad que necesita porque las partes comparten variables y flujo. Cada responsabilidad extra multiplica los caminos. La unidad de medida no son las líneas sino las razones de cambio: “leer, validar y guardar” hace tres cosas que evolucionan aparte.

Consecuencias de violarla

Tipo de consecuenciaEfecto concreto
Bug silenciosoCambiar la validación altera sin querer la parte de guardado.
ReutilizaciónLa lógica de cálculo queda inaccesible por estar mezclada con E/S.

Fundamento en el estándar y en la cátedra

El Principio de Responsabilidad Única proviene del diseño de software; en C11 se apoya en la función como unidad de compilación y prueba (§6.9.1). La cátedra lo adopta como eje del bloque 0x20XX (0x2002h: Las funciones no deben contener printf o scanf, a menos que ese sea su propósito explícito, 0x200Ah: Modularización: una función no debe exceder 4 parámetros de entrada, 0x2014h: Cada función debe caber en una sola idea y en 25 líneas).

Alcance y excepciones

Aplica a toda función con lógica. Una preparación seguida de un cálculo sigue siendo una sola responsabilidad si comparten una idea. El olor se detecta cuando el nombre necesita “y”, cuando la mitad del cuerpo se puede probar sin la otra o cuando hay parámetros bandera. Excepción: main es el orquestador y puede encadenar pasos que delegan en funciones.

Ejemplos exhaustivos

❌ Contraejemplo 1 — Leer, validar y promediar en un solo cuerpo

void procesar_edades(void)
{
    int edades[100];
    int n = 0;
    printf("Ingrese edades (-1 para terminar):\n");
    int x;
    while (n < 100 && scanf("%d", &x) == 1 && x != -1) {
        if (x >= 0 && x <= 120) {
            edades[n] = x;
            n++;
        }
    }
    double suma = 0.0;
    for (int i = 0; i < n; i++) {
        suma += edades[i];
    }
    printf("Promedio: %.2f\n", suma / n);
}

Hace entrada, validación, acumulación e impresión, y divide por cero si n es 0.

❌ Contraejemplo 2 — Parámetro bandera que esconde tres funciones

int calcular(int a, int b, int modo)
{
    if (modo == 1) {
        return a + b;
    } else if (modo == 2) {
        return a - b;
    } else {
        return a * b;
    }
}

modo elige entre tres operaciones: la función es tres disfrazadas y su nombre no describe ninguna (0x2009h: Los nombres de funciones y procedimientos deben usar snake_case en minúsculas). Además viola 0x2013h: Detector de bloques else superfluos tras sentencias terminales.

✅ Ejemplo conforme 1 — Cada responsabilidad en su función

static bool edad_valida(int edad)
{
    return edad >= 0 && edad <= 120;
}

static double promedio(const int edades[], size_t n)
{
    if (n == 0) {
        return 0.0;
    }
    long suma = 0;
    for (size_t i = 0; i < n; i++) {
        suma += edades[i];
    }
    return (double)suma / (double)n;
}

edad_valida responde una pregunta y promedio calcula una cosa, manejando el caso vacío. Ambas se prueban con un assert aislado.

✅ Ejemplo conforme 2 — Interfaz y cálculo separados

static void mostrar_promedio(double valor)
{
    printf("Promedio: %.2f\n", valor);
}

int main(void)
{
    int edades[] = {20, 30, 40};
    mostrar_promedio(promedio(edades, 3));
    return 0;
}

Cada paso cambia por un motivo distinto: uno por la fórmula, otro por el formato de pantalla (0x2002h: Las funciones no deben contener printf o scanf, a menos que ese sea su propósito explícito).

⚠️ Casos límite

Cómo detectarla

HerramientaComandoSeñal
gaffgaff check archivo.cFunción que supera el umbral de tamaño o anidación.
gigeranálisis de call graphFunciones que concentran llamadas heterogéneas.

Checklist de autocontrol

Reglas relacionadas