Cohesión de Componentes: El Principio de Reutilización Común
No obligues a los usuarios de un componente a depender de cosas que no necesitan — depender de un componente significa depender de todo lo que contiene.
Por qué importa
El Principio de Reutilización Común (CRP) nos dice qué clases no poner juntas en un componente: no fuerces a los usuarios de un componente a depender de cosas que no necesitan. Si un componente contiene la clase A y la clase B, un usuario que solo necesita la clase A igualmente debe depender de la clase B. Cuando la clase B cambia — aunque el usuario nunca la llame — ese usuario debe revalidar y potencialmente redesplegar su software.
CRP es el equivalente a nivel de componente del ISP. Ambos dicen lo mismo a diferentes escalas: no acoples a los consumidores con cosas que no usan. La disciplina práctica es asegurarse de que cada clase en un componente sea inseparable de las demás — que los usuarios del componente genuinamente necesiten todas las clases que contiene. Cuando una clase se "usa casi siempre" junto con ciertas otras clases, eso es una señal de CRP para agruparlas; cuando una clase es "a veces útil" junto a una clase no relacionada, eso es una señal de CRP para separarlas.
✗El problema
A containers package that includes GraphTraversal forces all consumers — even those using only List — to install heavy graph dependencies and retest when graph code changes.
Bad
# containers/ package bundles basic collections with a heavy graph algorithm
# list_impl.py — simple linked list
# map_impl.py — hash map
# queue_impl.py — FIFO queue
# graph_traversal.py — BFS/DFS, requires networkx (heavy dep!)
# A service that only needs List must install networkx.
# When graph_traversal.py changes, that service must re-validate
# its code — even though it never touches graph traversal.
// @company/containers bundles simple collections with heavy graph utilities
// packages/containers/src/
// LinkedList.ts — basic linked list
// HashMap.ts — hash map
// Queue.ts — FIFO queue
// GraphTraversal.ts — BFS/DFS (pulls in "graphlib" — heavy peer dep)
// A service using only LinkedList must list graphlib as a peer dependency
// and re-run tests every time GraphTraversal is modified.
✓La solución
GraphTraversal lives in its own package. Services that need only basic collections depend on containers — no graphlib, no graph churn.
Good
# containers/ — basic collections only
# list_impl.py
# map_impl.py
# queue_impl.py
# graph_algorithms/ — separate package, separate release cadence
# graph_traversal.py # requires networkx — only installed by graph users
# Services needing only List depend on "containers" — no networkx, no graph churn.
# Services needing BFS also depend on "graph_algorithms" — explicit, intentional.
// @company/containers — LinkedList, HashMap, Queue only
// @company/graph-algorithms — GraphTraversal, requires graphlib
// A service using LinkedList:
// import { LinkedList } from "@company/containers"; // no graphlib
// A service needing BFS:
// import { bfs } from "@company/graph-algorithms"; // explicit opt-in
💡Conclusión clave
CRP dice: no pongas clases en un componente si los usuarios del componente no necesitan todas las clases. Depender de un componente significa depender de todo lo que contiene — así que todo en un componente debe ser inseparable.
🔧 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: El CRP dice: no pongas clases en un componente si los usuarios del componente no necesitan todas las clases.
✗ Tu versión