Cohesión de Componentes: REP y CCP
REP agrupa las clases que se liberan juntas; CCP agrupa las que cambian juntas por la misma razón — ambas reflejan el SRP a escala de componente.
Por qué importa
El Principio de Equivalencia Reutilización/Publicación (REP) establece que el grano de reutilización es el grano de publicación. No puedes reutilizar código que no está rastreado y publicado — alguien debe poseerlo, versionarlo y proporcionar notas de publicación cuando cambie. Cualquier clase que quieras reutilizar debe pertenecer a un componente que esté correctamente empaquetado y publicado.
El Principio de Cierre Común (CCP) es el SRP a nivel de componente: agrupa en un único componente todas las clases que cambian por las mismas razones al mismo tiempo, y separa en componentes diferentes las clases que cambian por razones distintas. El beneficio práctico es enorme — si un cambio de requisito toca solo un componente, solo ese componente necesita recompilarse, reprobarse y redespliegarse. Un paquete "utilitario" que mezcla preocupaciones no relacionadas viola el CCP: cambiar cualquier preocupación obliga a todos los consumidores del paquete a actualizar, incluso aquellos que no usan ningún código cambiado.
✗El problema
A catch-all utilities package violates CCP — a change in PDF generation forces a new release that all dependents must adopt, even those that never touch PDF code.
Bad
# utils/ package — mixes HTTP helpers, date formatters, PDF and email
# http_helpers.py — HTTP request wrappers
# date_formatters.py — date parsing and display
# pdf_generator.py — PDF creation (heavy deps: reportlab, weasyprint)
# email_templates.py — HTML email builder
# PDF team updates pdf_generator.py → new "utils" version cut.
# Every service using only date_formatters must now upgrade, retest,
# and redeploy — even though nothing relevant to them changed.
// @company/utils — one package with unrelated concerns
// src/
// http.ts — axios wrappers
// dates.ts — date-fns helpers
// pdf.ts — puppeteer PDF export (heavy!)
// email.ts — Handlebars email builder
// A one-line change in pdf.ts bumps utils from 3.1.0 to 3.2.0.
// Every microservice importing only dates.ts must update their
// package.json, re-run CI, and redeploy. Unnecessary pain.
✓La solución
Each concern gets its own package with an independent release cadence. A change in pdf_utils is invisible to date_utils consumers.
Good
# http_utils/ v1.3.0 — HTTP helpers only
# wrappers.py
# date_utils/ v2.1.0 — date parsing and display only
# formatters.py
# pdf_utils/ v0.9.0 — PDF generation only
# generator.py
# email_utils/ v1.0.2 — email templates only
# templates.py
# A change in pdf_utils triggers only a pdf_utils release.
# date_utils users are unaffected — no forced upgrade, no forced redeploy.
// @company/http-utils v1.3.0 — axios wrappers
// @company/date-utils v2.1.0 — date-fns helpers
// @company/pdf-utils v0.9.0 — puppeteer PDF export
// @company/email-utils v1.0.2 — email templates
// A change in @company/pdf-utils only touches pdf consumers.
// Services using @company/date-utils see zero churn — no forced upgrades.
💡Conclusión clave
Si las clases en un componente no cambian por la misma razón, no pertenecen al mismo componente. CCP a nivel de componente es SRP a nivel de clase — separa lo que cambia separadamente.
🔧 Algunos ejercicios pueden tener errores. Si algo parece incorrecto, usa el botón Feedback (abajo a la derecha) para reportarlo — nos ayuda a corregirlo rápido.
Pista: Si las clases de un componente no cambian por la misma razón, no deberían estar en el mismo componente.
✗ Tu versión