Lógica de negocio y lógica de aplicación
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.
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.
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.
fun createOrder(products: Set<Pair<String, Int>>): Map<String, Int> {
require(products.isNotEmpty()) {
"Un pedido debe tener al menos un ítem."
}
return products.toMap()
}
createOrder
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)
}
createOrder
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")
}
createOrder
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?
Referencias recomendadas
- “ Qué es la lógica de negocio en programación y cómo distinguirla de la lógica de aplicación y de pantalla ” por Albert CapdevilaExplica cómo diferenciar tres tipos de lógica en un sistema de software: lógica de negocio (reglas e invariantes del dominio), lógica de aplicación (coordinación técnica y persistencia) y lógica de pantalla (decisiones de interfaz). A través de ejemplos claros, como facturas y gestión de stock, muestra cómo ubicar cada tipo de lógica en la arquitectura y cómo esta separación favorece la comunicación en el equipo y la mantenibilidad del código.