Un sistema pot fer exactament allò que se li va demanar —complir tots els seus requisits funcionals— i tot i així ser un fracàs: perquè és lent, cau cada setmana, no resisteix un atac o costa una fortuna mantenir-lo. Tot això ho governen els atributs de qualitat, també anomenats requisits no funcionals. Són, en gran mesura, allò que l'arquitectura busca aconseguir: el "com de bé" davant del "què fa". En aquesta lliçó aprendràs a identificar-los, a distingir-los dels requisits funcionals i, sobretot, a especificar-los de manera mesurable mitjançant escenaris de qualitat, perquè un atribut que no es pot mesurar no es pot dissenyar ni verificar.
Contingut
- Funcionals davant de no funcionals
- Catàleg d'atributs de qualitat
- El problema dels requisits vagues
- Escenaris de qualitat: com especificar-los
- Tàctiques arquitectòniques per aconseguir-los
- Conflictes entre atributs
- Funcionals davant de no funcionals
Convé tenir clara la frontera des del principi.
| Tipus de requisit | Respon a | Exemple |
|---|---|---|
| Funcional | Què fa el sistema? | "L'usuari pot transferir diners entre els seus comptes" |
| No funcional (atribut de qualitat) | Com de bé ho fa? | "La transferència es completa en menys de 2 segons el 99% de les vegades" |
Els requisits no funcionals també es coneixen com a atributs de qualitat, NFR (Non-Functional Requirements) o -ilities en anglès (scalability, availability, etc.). Són responsabilitat directa de l'arquitectura: la funcionalitat es pot implementar de moltes maneres, però només algunes estructures aconsegueixen la disponibilitat o el rendiment exigits.
- Catàleg d'atributs de qualitat
Existeixen taxonomies formals (per exemple, la norma ISO/IEC 25010). A continuació, els atributs més rellevants a la pràctica:
| Atribut | Definició breu | Com se sol mesurar |
|---|---|---|
| Rendiment | Rapidesa de resposta i ús eficient de recursos | Latència (ms), throughput (peticions/s) |
| Escalabilitat | Capacitat de créixer davant de més càrrega | Usuaris concurrents suportats, cost per unitat de càrrega |
| Disponibilitat | Proporció de temps operatiu | % d'uptime (p. ex., 99,9%), MTBF, MTTR |
| Fiabilitat | Funcionar correctament sense fallades | Taxa d'errors, fallades per milió d'operacions |
| Seguretat | Protegir dades i funcions d'accessos indeguts | Vulnerabilitats, compliment de normatives |
| Mantenibilitat | Facilitat de canvi i correcció | Temps mitjà d'implementar un canvi, complexitat |
| Testabilitat | Facilitat de provar el sistema | Cobertura, temps de la suite de proves |
| Usabilitat | Facilitat d'ús per a l'usuari final | Taxa de tasques completades, temps d'aprenentatge |
| Observabilitat | Capacitat d'entendre l'estat intern des de fora | Cobertura de logs, mètriques i traces |
| Portabilitat | Facilitat de moure el sistema a un altre entorn | Esforç de migració |
Nota sobre disponibilitat: el percentatge d'uptime té conseqüències molt concretes en temps de caiguda tolerat a l'any.
| Disponibilitat | Caiguda màxima a l'any (aprox.) |
|---|---|
| 99% ("dos nous") | ~3,65 dies |
| 99,9% ("tres nous") | ~8,77 hores |
| 99,99% ("quatre nous") | ~52,6 minuts |
| 99,999% ("cinc nous") | ~5,26 minuts |
Cada "nou" addicional dispara el cost i la complexitat. Per això és un atribut que s'ha de negociar amb el negoci, no fixar-lo al màxim "per si de cas".
- El problema dels requisits vagues
Compara aquestes dues maneres d'expressar el mateix requisit:
- Vague: "El sistema ha de ser ràpid."
- Mesurable: "El 95% de les cerques de productes han de respondre en menys de 300 ms amb 1.000 usuaris concurrents."
El primer és inútil: ràpid per a qui, en quina operació, sota quina càrrega, amb quin objectiu? No es pot dissenyar contra ell ni verificar si es compleix. El segon és mesurable, específic i verificable. La regla d'or és:
Un atribut de qualitat que no és mesurable no és un requisit, és un desig.
- Escenaris de qualitat: com especificar-los
El SEI (Software Engineering Institute) proposa els escenaris de qualitat com a forma estàndard d'especificar atributs no funcionals. Un escenari té sis parts:
| Part | Significat | Exemple (rendiment) |
|---|---|---|
| Font de l'estímul | Qui/què genera l'esdeveniment | Un usuari extern |
| Estímul | L'esdeveniment que arriba | Llança una cerca de productes |
| Artefacte | Part del sistema afectada | El servei de catàleg |
| Entorn | Condicions en què passa | En hora punta, amb 1.000 usuaris concurrents |
| Resposta | Què fa el sistema | Retorna els resultats de la cerca |
| Mesura de la resposta | Criteri d'èxit quantificable | En menys de 300 ms el 95% de les vegades |
Llegit de corrido: "Un usuari extern llança una cerca de productes en el servei de catàleg en hora punta amb 1.000 usuaris concurrents; el sistema retorna els resultats en menys de 300 ms el 95% de les vegades."
Podem representar-ho de manera estructurada:
escenari_qualitat:
atribut: rendiment
font: usuari_extern
estimul: cerca_de_productes
artefacte: servei_cataleg
entorn: hora_punta_1000_usuaris_concurrents
resposta: retornar_resultats_cerca
mesura:
metrica: temps_resposta_ms
objectiu: 300
percentil: 95 # el 95% de les peticions ha de complir l'objectiuAquest YAML formalitza l'escenari perquè es pugui discutir i verificar. L'important no és el format concret, sinó que cada escenari inclogui les sis parts. El camp percentil: 95 és clau: especificar un percentil (P95, P99) en lloc d'una mitjana evita enganys, perquè una mitjana baixa pot amagar un petit percentatge de peticions desastrosament lentes que arruïnen l'experiència.
Un escenari de disponibilitat es podria escriure així:
escenari_qualitat:
atribut: disponibilitat
font: node_del_sistema
estimul: caiguda_inesperada_d_una_instancia
artefacte: servei_de_pagaments
entorn: operacio_normal
resposta: redirigir_transit_a_instancia_sana_sense_perdua_de_dades
mesura:
objectiu_uptime: "99.9%"
temps_recuperacio_max_segons: 30Aquí l'estímul no ve d'un usuari, sinó d'una fallada interna (la caiguda d'una instància). La resposta esperada és que el sistema es recuperi automàticament redirigint el trànsit, amb un objectiu de disponibilitat del 99,9% i un temps de recuperació màxim de 30 segons. Especificar-ho així permet dissenyar i provar la tolerància a fallades de manera concreta.
- Tàctiques arquitectòniques per aconseguir-los
Una tàctica és una decisió de disseny que influeix en un atribut de qualitat concret. Algunes d'habituals:
- Rendiment: memòria cau, índexs, balanceig de càrrega, processament asíncron.
- Disponibilitat: redundància, failover automàtic, health checks, circuit breakers.
- Escalabilitat: escalat horitzontal (més instàncies), particionat de dades (sharding), cues per absorbir pics.
- Seguretat: autenticació i autorització, xifratge en trànsit i en repòs, principi de mínim privilegi.
- Mantenibilitat: baix acoblament, alta cohesió, modularitat, proves automatitzades.
// Exemple de tàctica de disponibilitat: un circuit breaker simplificat.
// Si un servei dependent falla repetidament, deixem de cridar-lo un temps
// per no esgotar recursos i donar marge que es recuperi ("fail fast").
public class CircuitBreaker {
private int fallidesConsecutives = 0;
private final int llindar = 5; // a partir de 5 fallides, obrim el circuit
private boolean obert = false;
public Resposta cridar(ServeiRemot servei) {
if (obert) {
// Circuit obert: no cridem, retornem una resposta de reserva.
return Resposta.degradada();
}
try {
Resposta r = servei.invocar();
fallidesConsecutives = 0; // èxit: reiniciem el comptador
return r;
} catch (Exception e) {
fallidesConsecutives++;
if (fallidesConsecutives >= llindar) {
obert = true; // massa fallides: obrim el circuit
}
return Resposta.degradada();
}
}
}Aquest exemple Java implementa de manera molt simplificada el patró circuit breaker (tallacircuits), una tàctica clàssica de disponibilitat. La idea: si un servei remot falla llindar vegades seguides (fallidesConsecutives >= llindar), el circuit s'"obre" (obert = true) i deixem de cridar-lo, retornant una resposta degradada immediata en lloc d'esperar que torni a fallar. Això evita que un servei caigut arrossegui tot el sistema (efecte dòmino) i li dona temps per recuperar-se. En producció s'usarien llibreries madures com Resilience4j, però el concepte és aquest.
- Conflictes entre atributs
Els atributs de qualitat gairebé mai no són independents: millorar-ne un sol perjudicar-ne un altre. Per això l'arquitectura és l'art dels compromisos (que veurem en detall en la lliçó següent).
| Si millores... | Pots perjudicar... | Motiu |
|---|---|---|
| Seguretat (més xifratge/validacions) | Rendiment | El xifratge i les comprovacions consumeixen temps |
| Disponibilitat (més redundància) | Cost | Més servidors i replicació costen diners |
| Rendiment (més memòria cau) | Consistència | Les dades en memòria cau poden quedar obsoletes |
| Escalabilitat (sistemes distribuïts) | Mantenibilitat/simplicitat | Allò distribuït és més complex d'operar i depurar |
La conclusió pràctica és que no existeix l'arquitectura "òptima" en abstracte: existeix l'arquitectura adequada per a un conjunt prioritzat d'atributs de qualitat. Per això la primera feina de l'arquitecte és aconseguir que el negoci prioritzi: què importa més, el cost o la disponibilitat?, la velocitat o la consistència perfecta?
Errors Comuns i Consells
- Deixar els NFR per al final. Els atributs de qualitat s'han de capturar a l'inici, perquè condicionen tota l'estructura. Afegir disponibilitat a un sistema que no es va dissenyar per a ella és caríssim.
- Especificar-los de manera vaga. "Ràpid", "segur", "escalable" no són requisits. Usa escenaris de qualitat amb mesures concretes.
- Demanar el màxim en tot. Voler cinc nous de disponibilitat, latència mínima i cost mínim alhora és contradictori. Cal prioritzar.
- Usar mitjanes en lloc de percentils. Una mitjana amaga els casos pitjors. Mesura P95/P99.
- Consell: converteix cada NFR en quelcom verificable. Si no saps com mesurar que es compleix, reescriu-lo fins que puguis.
Exercicis
Exercici 1. Reescriu el requisit vague següent en un escenari de qualitat amb les seves sis parts: "El sistema de login ha de ser segur i ràpid".
Exercici 2. Una botiga en línia exigeix un 99,99% de disponibilitat. Quant de temps de caiguda a l'any tolera, aproximadament? Quines dues tàctiques proposaries per assolir-lo i quin atribut es veuria perjudicat?
Exercici 3. Identifica el conflicte entre atributs en aquesta decisió: "Xifrarem totes les dades a la base de dades i validarem cada camp en tres capes diferents". Quin atribut millora i quin se'n ressent?
Solucions
Solució 1. Exemple d'escenari per a la part de rendiment del login: Font: un usuari registrat. Estímul: envia les seves credencials. Artefacte: el servei d'autenticació. Entorn: operació normal amb 500 usuaris concurrents. Resposta: valida les credencials i retorna un token de sessió. Mesura: en menys de 500 ms el 99% de les vegades. (Per a la part de seguretat es redactaria un altre escenari a part, p. ex.: davant de 5 intents fallits en 1 minut des de la mateixa IP, el sistema bloqueja el compte i registra l'esdeveniment de seguretat.)
Solució 2. El 99,99% tolera aproximadament 52,6 minuts de caiguda a l'any. Tàctiques possibles: redundància amb diverses instàncies en diferents zones i failover automàtic amb balancejador i health checks. L'atribut perjudicat és principalment el cost (més infraestructura i replicació), i secundàriament la complexitat/mantenibilitat operativa.
Solució 3. Millora la seguretat (xifratge i validació exhaustiva). Se'n ressent el rendiment: el xifratge/desxifratge i la triple validació afegeixen latència i consum de CPU en cada operació. També pot afectar la mantenibilitat si la validació està duplicada en tres capes sense una única font de veritat.
Conclusió
Has après a distingir requisits funcionals de no funcionals, a manejar un catàleg d'atributs de qualitat, a especificar-los de manera mesurable amb escenaris de qualitat de sis parts, a aplicar tàctiques per aconseguir-los i a reconèixer que gairebé sempre entren en conflicte entre si. Precisament aquest xoc permanent entre atributs —disponibilitat contra cost, rendiment contra consistència— és el cor de la feina arquitectònica. En la lliçó següent abordarem de front com es prenen aquestes decisions difícils: les decisions arquitectòniques i els compromisos (trade-offs), incloent-hi mètodes formals d'avaluació com ATAM.
Curs d'Arquitectura d'Aplicacions
Mòdul 1: Fonaments de l'Arquitectura d'Aplicacions
- Què és l'Arquitectura d'Aplicacions?
- El Rol de l'Arquitecte de Programari
- Atributs de Qualitat i Requisits No Funcionals
- Decisions Arquitectòniques i Compromisos (Trade-offs)
- Documentació d'Arquitectura: Vistes i el Model C4
Mòdul 2: Principis i Tàctiques de Disseny
- Acoblament, Cohesió i Separació de Responsabilitats
- Principis SOLID Aplicats a l'Arquitectura
- DRY, KISS, YAGNI i Altres Principis de Disseny
- Tàctiques Arquitectòniques per als Atributs de Qualitat
- Gestió del Deute Tècnic
Mòdul 3: Estils i Patrons Arquitectònics
- Arquitectura Monolítica
- Arquitectura en Capes (N-Tier)
- Arquitectura Client-Servidor
- Arquitectura Hexagonal (Ports i Adaptadors)
- Arquitectura Neta i Ceba (Clean & Onion)
Mòdul 4: Arquitectures Distribuïdes i Microserveis
- Introducció als Sistemes Distribuïts
- Arquitectura de Microserveis
- Descomposició de Serveis i Bounded Contexts
- API Gateway, Service Discovery i Comunicació entre Serveis
- Patrons de Resiliència: Circuit Breaker, Retry i Bulkhead
- El Teorema CAP i la Consistència de Dades
Mòdul 5: Arquitectures Dirigides per Esdeveniments i Missatgeria
- Fonaments de l'Arquitectura Orientada a Esdeveniments
- Missatgeria Asíncrona: Cues i Brokers
- Patrons d'Esdeveniments: Event Sourcing i CQRS
- Gestió de Transaccions Distribuïdes: Patró Saga
- Streaming de Dades en Temps Real
Mòdul 6: Disseny Dirigit pel Domini (DDD)
- Conceptes Fonamentals del DDD
- Disseny Estratègic: Bounded Contexts i Llenguatge Ubic
- Disseny Tàctic: Entitats, Agregats i Repositoris
- Mapatge de Contextos (Context Mapping)
Mòdul 7: Dades i Persistència
- Estratègies de Persistència: SQL vs NoSQL
- Patrons d'Accés a Dades: Repository, Unit of Work i DAO
- Base de Dades per Servei i Gestió de Dades Distribuïdes
- Cau i Estratègies d'Invalidació
Mòdul 8: Arquitectura al Núvol i Desplegament
- Fonaments del Cloud Computing (IaaS, PaaS, SaaS)
- Contenidors i Orquestració amb Docker i Kubernetes
- Arquitectura Serverless
- Patrons de Disseny Cloud-Native
- Infraestructura com a Codi (IaC)
Mòdul 9: Qualitat, Seguretat i Observabilitat
- Escalabilitat: Horitzontal vs Vertical i Balanceig de Càrrega
- Alta Disponibilitat i Tolerància a Fallades
- Seguretat per Disseny i Autenticació/Autorització
- Observabilitat: Logging, Mètriques i Traçabilitat
- Rendiment i Proves de Càrrega
