Lógica de negocio y lógica de aplicación

Abstract

En la lección anterior entendimos que una biblioteca es, en esencia, una API: un conjunto de funciones, tipos y abstracciones diseñadas para ser reutilizadas en distintos contextos. Pero surge una pregunta clave: ¿qué ponemos dentro de la biblioteca y qué dejamos fuera?

La respuesta está en distinguir entre lógica de negocio —las reglas e invariantes que definen el dominio y permanecen estables— y lógica de aplicación —la capa que traduce, coordina y adapta esas reglas a un entorno tecnológico concreto (frameworks, bases de datos, interfaces, protocolos).

Comprender esta separación es fundamental para construir bibliotecas reutilizables, mantenibles y resistentes al cambio tecnológico.

Lógica de negocio

La lógica de negocio (business logic), a veces también llamada core del sistema, representa las reglas, invariantes y operaciones fundamentales del dominio que queremos modelar. Es lo que permanece estable incluso si cambiamos la interfaz de usuario, el framework web o la forma en que desplegamos el sistema.

  • Define el qué hace el sistema, no el cómo se presenta o ejecuta.
  • Vive en la biblioteca, porque es lo que buscamos reutilizar, probar y mantener aislado de los detalles externos.

Ejemplo: Sistema de pedidos en un e-commerce

Si estamos construyendo un sistema de pedidos en un e-commerce, la lógica de negocio define reglas como:

  • Un pedido debe tener al menos un ítem.
  • No se puede despachar un pedido que no esté pagado.
  • El cálculo del total considera descuentos y envío.

Tip

La lógica de negocio no depende de si la aplicación es web, móvil o de línea de comandos: cambian las interfaces, pero las reglas se mantienen.

Lógica de aplicación

La lógica de aplicación se refiere al entorno donde la lógica de negocio se usa y coordina. Incluye los detalles de frameworks, almacenamiento, presentación y orquestación de acciones. A diferencia de la lógica de negocio, suele cambiar con mayor frecuencia porque depende de tecnologías y protocolos.

  • Define el cómo interactúan las personas usuarias o sistemas externos con la lógica de negocio.
  • No pertenece a la biblioteca: vive en un servicio, aplicación o interfaz.

Ejemplo: Backend web para e-commerce

Si seguimos con el ejemplo del sistema de pedidos, la lógica de aplicación se encarga de:

  • Recibir una solicitud HTTP para crear un pedido.
  • Convertir la entrada JSON a objetos de negocio (Order, Item).
  • Llamar a las funciones de la lógica de negocio.
  • Guardar el resultado en una base de datos.
  • Responder con un código HTTP apropiado.

La biblioteca contiene la lógica de negocio

Al separar estas dos capas, queda claro qué debe ir en la biblioteca:

  • La biblioteca implementa la lógica de negocio.
  • La aplicación integra esa lógica con tecnologías concretas (frameworks web, CLI, UI, etc.).

Esto trae beneficios:

  • Reutilización: la misma lógica de negocio puede usarse en una app web, móvil o un script de automatización.
  • Pruebas más simples: es posible verificar reglas del negocio sin depender de HTTP, bases de datos o UI.
  • Mantenibilidad: los cambios en frameworks o detalles técnicos no afectan las reglas del dominio.
  • Portabilidad: si mañana cambiamos de framework, la lógica de negocio sigue siendo válida.

Nota

Aunque la distinción suele ser clara, la línea entre lógica de negocio y lógica de aplicación puede ser difusa en ciertos escenarios. Por ejemplo, la interacción con una base de datos normalmente pertenece a la lógica de aplicación. Sin embargo, podríamos diseñar una biblioteca que modele cómo se consulta o persiste información, siempre a través de abstracciones. La conexión concreta a la base de datos (drivers, pools, transacciones) sigue ocurriendo en la capa de aplicación.

Ejemplo real

La misma función de lógica de negocio se usa desde dos contextos de lógica de aplicación: una API REST y una interfaz de usuario. Observa cómo las reglas viven en la biblioteca, y la orquestación/delivery vive en la aplicación.

Para ilustrar esto usaremos Ktor (un framework ligero para crear servidores en Kotlin) y Compose (un toolkit para construir interfaces declarativas). Podríamos haber usado otras alternativas, como Spring Boot o Micronaut en lugar de Ktor, o JavaFX en lugar de Compose. El punto clave es que las tecnologías de aplicación pueden cambiar, mientras que la lógica de negocio permanece en la biblioteca.

Lógica de negocio: valida las reglas e implementa el dominio.
fun createOrder(products: Set<Pair<String, Int>>): Map<String, Int> {
    require(products.isNotEmpty()) {
      "Un pedido debe tener al menos un ítem."
    }
    return products.toMap()
}
Lógica de aplicación (API REST): adapta HTTP↔️dominio y delega en createOrder .
post("/orders") {
    // Lógica de aplicación:
    // 1) Recibir datos externos (JSON: {"skuA": 2, "skuB": 1})
    val body: Map<String, Int> = call.receive()

    // 2) Convertir entrada a tipos del dominio
    val products: Set<Pair<String, Int>> =
        body.entries.map { it.key to it.value }.toSet()

    // 3) Invocar la lógica de negocio
    val order: Map<String, Int> = createOrder(products)

    // 4) Responder (p. ej., 201 + contenido)
    call.respond(order)
}
Lógica de aplicación (UI): obtiene datos de la vista, llama a createOrder y presenta el resultado.
@Composable
fun OrderScreen() {
    // Lógica de aplicación (UI):
    // Preparar entrada desde la vista (ejemplo minimal)
    val selectedProducts: Set<Pair<String, Int>> =
        setOf("skuA" to 2, "skuB" to 1)

    // Delegar la regla de negocio al core
    val order: Map<String, Int> = createOrder(selectedProducts)

    // Mostrar resultado (presentación)
    val totalItems = order.values.sum()
    Text(text = "Pedido creado · ítems: $totalItems")
}

Tip

Las reglas del dominio se mantienen en la función de la biblioteca. La aplicación solo traduce entradas/salidas (HTTP, UI) y orquesta el flujo. Cambiar Ktor por otro framework web, o Compose por otro toolkit de UI, no afecta la validez de createOrder .

Conclusiones

La distinción entre lógica de negocio y lógica de aplicación nos entrega una brújula clara para decidir qué debe vivir en una biblioteca y qué pertenece a la aplicación. La primera concentra las reglas del dominio y se mantiene estable, mientras que la segunda traduce y orquesta esas reglas en entornos concretos como APIs, interfaces gráficas o servicios en la nube.

Esta separación no solo favorece la reutilización, pruebas más simples y portabilidad, sino que también nos prepara para el siguiente paso: preguntarnos cómo representamos esas reglas e invariantes en código. Es aquí donde entran en juego los modelos de dominio.

Puntos clave

  • La biblioteca implementa la lógica de negocio: reglas, invariantes y operaciones fundamentales del dominio.
  • La aplicación implementa la lógica de aplicación: frameworks, UI, bases de datos y orquestación de acciones.
  • Separar ambas capas aumenta la reutilización, la mantenibilidad y la portabilidad de las soluciones.
  • Esta división abre paso a diseñar modelos de dominio más expresivos, precisos y alineados con las necesidades reales.

¿Qué nos llevamos?

El gran aprendizaje es que las bibliotecas deben capturar el corazón del dominio, mientras que la aplicación se adapta al contexto tecnológico. Con esta base clara, estamos listxs para explorar cómo dar forma a esas reglas a través de modelos de dominio: estructuras de datos y tipos que representan con precisión el mundo que queremos modelar.

¿Con ganas de más?