Trabe
Asís & David
https://trabe-teaching.github.io/wrong-abstractions
Las abstracciones equivocadas
Sobre nosotros
- Desarrollamos front/back con JS (+15 años).
- Hemos trabajado con múltiples stacks y frameworks: RoR, JEE, .NET, PHP.
- Hemos desarrollado frameworks para otros desarrolladores.
...una gran corporación que quería desarrollar un conjunto de frameworks para aumentar la productividad de sus equipos de desarrollo.
Qué "querían"
- Soporte para crear microservicios Java/Node y SPAs con JS/React.
- Reducir el boilerplate (el problema que tenían).
- Rebajar la barrera de entrada a sus múltiples equipos de "perfiles variados".
- Componentes adaptados a sus casos de uso y a la corporación (imagen corporativa, infraestructura común, etc.).
- Desplegable en la nube (con todo bien integrado).
Qué les dimos
- Una serie de abstracciones rígidas que simplifican el desarrollo: todas las apps/servicios son similares, comparten imagen e infraestructura común. Solo cambia la lógica de negocio.
- Desplegable en su nube (todo bien integrado).
// Quiero un microservicio que en el endpoint /products
// devuelve una lista de productos, cuyos datos salen
// de una API REST de items, que hay que procesar.
service()
.use(auth())
.mount(router()
.get("/products",
fetchJson("http://api/items"),
transform(mapItemToProduct)
)
)
service:
port: 3000
auth:
enabled: true
log:
level: DEBUG
transports:
- kafka
tracing:
threshold: 0.5
Tragedia en 5 pasos
- Se definen unos requisitos cerrados.
- Se entrega un producto que los cumple.
- El producto "no vale". Las abstracciones son muy rígidas. Los requisitos estan mal. Todo debe ser más flexible.
- Se sugiere una nueva major con abstracciones más simples.
- Imposible. "Hay que poner en valor lo que hay". Se extienden las abstracciones para hacerlas "configurables".
service()
.use(auth())
.mount(router()
.get("/products",
fetchJson("http://api/items", {
onError: async (e,ctx, next) => {
ctx.state.data = [];
await next();
}
})
)
)
Framework
API + implementación
La abstracción equivocada
- Nuestras APIs cubren el caso de uso general, con una configuración mínima.
- Algún equipo quiere hacer algo distinto.
- Se extiende la API con (red) flags, etc.
¿Hacer algo distinto?
- Implementar casos de uso particulares.
- Usar infraestructura diferente.
- Desplegar en otro entorno.
- Usar partes sueltas del framework.
Es decir... los requisitos reales.
No tendría por qué ser así.
La abstracción correcta
- Nuestras APIs cubren el caso de uso base.
- Los equipos pueden hacer lo que les da la gana. Usarlo o no usarlo.
- El caso general se cubre con: wrappers o boilerplate extraido a librerías (con inyección de dependencias), patrones de uso y documentación.
//before
fetchJson("http://api/items")
// after
fetchData(() => fetchClient.json("http://api/items"))
// before
fetchJson("http://api/items", {
onError: async (e,ctx, next) => {
ctx.state.data = []
await next();
}
})
// after
fetchData(async () => {
try {
return await fetchClient.json("http://api/items");
} catch {
return [];
}
})
Tragedia en 5 7 pasos
- Se definen unos requisitos cerrados.
- Se entrega un producto que los cumple.
- El producto "no vale". Las abstracciones son muy rígidas. Los requisitos estan mal. Todo debe ser más flexible.
- Se sugiere una nueva major con abstracciones más simples.
- Imposible. "Hay que poner en valor lo que hay". Se extienden las abstracciones para hacerlas "configurables".
- Vamos a pivotar. Una "IA" escribe el boilerplate. Necesitamos un framework de piezas sencillas.
- Se pide una major con abstracciones más simples, pero "hay que poner en valor lo que hay".
Lecciones aprendidas
- Usar abstracción correcta siempre, aunque no sea requisito.
- Siempre abstracciones básicas y componibles aunque no sean API pública inicialmente.
- Garantizar flexibilidad futura.
- El problema de la extracción de requisitos.
- Los requisitos siempre cambian.
- El software evoluciona orgánicamente.
- Diseña para el cambio.
La "IA" escribe el boilerplate
Las tecnologías equivocadas
Estar en la cresta de la ola
"IA" pros
- Si funcionase, todos. 😬
- El "business" (¡viva el hype!).
- Barrera de entrada baja.
- UIs de lenguaje natural.
"IA" cons (1)
- Problema de escala.
- Volumen de datos: latrocinio y explotación.
- Gasto energético: ecología.
- Volumen de inversión: ¿retorno?
- Herramienta para todo y para nada.
- Fuerza bruta (golden hammer).
- "Halucinaciones".
- Slop.
"IA" cons (2)
- Tecnofascimos.
- No es opt-in (ni opt-out).
- Deskilling (en el más amplio sentido).
- Delegación de responsabilidad.
- Adicción.
- Democratización (my ass).