1. Skip to content

1. Fundamentos

Principios fundamentales de código limpio, mantenible y escalable que aplican a cualquier lenguaje o framework.


1.1 📊 Niveles de Criticidad

Ver Tabla de Niveles de Criticidad en el Índice General.


1.2 🌐 Fundamentos de Red

¿Por qué? Comprender cómo se comunican los sistemas es fundamental para desarrollar aplicaciones distribuidas, APIs y servicios en la nube.

¿Quién? Todo desarrollador, especialmente aquellos trabajando con aplicaciones web, APIs y microservicios.

¿Cuánto cuesta? Conocimiento base esencial, inversión de 1-2 días para conceptos fundamentales.

Concepto Qué es Por qué Cuándo aplicarlo Dónde Cómo Recurso
Modelo Cliente-Servidor Arquitectura donde clientes solicitan recursos/servicios y servidores los proveen Base de la mayoría de aplicaciones web y distribuidas En toda aplicación que requiera comunicación entre componentes Web apps, APIs, microservicios Cliente envía request (HTTP, gRPC), servidor procesa y responde MDN - Client-Server
Dirección IP Identificador único de un dispositivo en una red (IPv4: 192.168.1.1, IPv6: 2001:0db8::1) Permite enrutar paquetes al destino correcto Configuración de servidores, debugging de red, seguridad Networking, deployment, firewall rules IPv4 (32 bits, 4 octetos), IPv6 (128 bits, 8 grupos hex). Privadas (10.x, 172.31.x, 192.168.x) vs Públicas Wikipedia - IP Address
DNS Domain Name System - Traduce nombres de dominio (example.com) a direcciones IP Humanos recuerdan nombres, máquinas usan IPs Al configurar dominios, troubleshooting de conectividad Todos los servicios web, email, CDN Cliente consulta DNS resolver → obtiene IP → conecta. Tipos: A (IPv4), AAAA (IPv6), CNAME (alias), MX (email) Cloudflare - What is DNS
Puertos Número que identifica un servicio específico en un host (0-65535) Múltiples servicios en misma IP Al exponer servicios, configurar firewalls Servidores, contenedores, load balancers Well-known: HTTP (80), HTTPS (443), SSH (22), PostgreSQL (5432). Especificar en IP:Puerto Wikipedia - Port
Protocolo HTTP/HTTPS Protocolo de transferencia de hipertexto (seguro con TLS) Comunicación estándar web Toda API REST, aplicación web Frontend-Backend, APIs públicas Request (método, headers, body) → Response (status, headers, body). HTTPS cifra con TLS MDN - HTTP
Load Balancer Distribuye tráfico entre múltiples servidores Escalabilidad horizontal, alta disponibilidad Aplicaciones con múltiples instancias Arquitecturas escalables, microservicios Algoritmos: Round Robin, Least Connections, IP Hash. Ver también Networking en Cloud NGINX - Load Balancing

1.2.1 Ejemplo: Flujo Cliente-Servidor con DNS

sequenceDiagram
    participant Cliente
    participant DNS
    participant LoadBalancer
    participant Servidor1
    participant Servidor2

    Cliente->>DNS: ¿Cuál es la IP de api.example.com?
    DNS-->>Cliente: 203.0.113.10
    Cliente->>LoadBalancer: GET /users (203.0.113.10:443)
    LoadBalancer->>Servidor1: Forward request
    Servidor1-->>LoadBalancer: Response {users: [...]}
    LoadBalancer-->>Cliente: Response {users: [...]}

    Note over Cliente,Servidor2: Siguiente request puede ir a Servidor2

1.3 🧠 Reglas Generales de Código

¿Por qué? Estos principios son la base de código profesional que resiste el paso del tiempo y facilita el trabajo en equipo.

¿Quién? Todo desarrollador del equipo, sin importar su rol o nivel de experiencia.

¿Cuánto cuesta? Inversión inicial en aprendizaje (1-2 semanas), ahorro exponencial en mantenimiento.

Nivel Principio Qué es Por qué Cuándo aplicarlo Dónde Cómo Recurso
🔴 SOLID Conjunto de 5 principios para diseño OOP mantenible: SRP, OCP, LSP, ISP, DIP Reduce acoplamiento, aumenta cohesión, facilita testing y extensibilidad En toda clase, servicio o módulo con responsabilidades Servicios, controladores, clases de dominio SRP: una clase = una razón para cambiar. OCP: abierto a extensión, cerrado a modificación Clean Coder
🔴 HC/LC High Cohesion, Low Coupling - Objetos enfocados y poco dependientes Cohesión: código relacionado junto. Acoplamiento: dependencias mínimas. Es la meta de SOLID y GRASP. Al diseñar cualquier módulo o asignar responsabilidades Arquitectura, paquetes, clases Alta Cohesión: Clase hace una sola cosa bien. Bajo Acoplamiento: Cambiar A no rompe B. GeeksforGeeks
🟢 KISS Keep It Simple, Stupid - Favorecer soluciones simples Código simple es más fácil de entender, mantener y depurar Siempre, al diseñar cualquier solución Toda lógica de negocio, algoritmos Evitar condicionales anidados, abstracciones innecesarias, over-engineering FreeCodeCamp
🟠 DRY Don't Repeat Yourself - Evitar duplicación de lógica Cambios se hacen en un solo lugar, reduce bugs por inconsistencias Al detectar código o lógica duplicada (regla de 3) Funciones, componentes, servicios Extraer a función reutilizable, usar composición, herencia con cuidado TechTarget
🟠 YAGNI You Aren't Gonna Need It - No implementar funcionalidades futuras Reduce complejidad, ahorra tiempo, evita código muerto Ante tentación de agregar "por las dudas" Todo el código Implementar solo lo que pide el requisito actual, iterar después C2 Wiki
🟢 Curly's Law Una función = una responsabilidad clara Facilita testing, comprensión y reutilización Al escribir cualquier función o método Funciones, métodos Nombre describe acción única, intentando que ocupe 30 líneas, sin efectos colaterales ocultos Coding Horror
🟢 DMMT Don't Make Me Think - Código intuitivo y autoexplicativo Reduce carga cognitiva, acelera onboarding Al nombrar variables, estructurar módulos Nombres, estructuras, APIs Variables descriptivas (isUserAuthenticated vs flag), flujos lineales Wikipedia
🟠 PORE Premature Optimization is the Root of Evil - Optimizar basado en datos Evita complejidad sin beneficio real Solo tras profiling que muestre bottleneck Código con problemas de rendimiento reales Medir con profiler, optimizar cuello de botella, re-medir C2 Wiki
🟢 BSR Boy Scout Rule - Dejar el código mejor que lo encontraste Mejora incremental continua En cada commit, cada PR Cualquier archivo que toques Renombrar variable confusa, extraer función, agregar test Snappify
🟢 CFM Code for the Maintainer - Escribir pensando en quien mantendrá Reduce frustración, facilita debugging futuro Al escribir cualquier código no trivial Todo el código Documentar decisiones no obvias, evitar "hacks inteligentes", README claro C2 Wiki
🟠 POLA Principle of Least Astonishment - Comportamiento esperado Usuario/developer no se sorprende Al diseñar APIs, interfaces, funciones APIs públicas, UIs, funciones deleteUser() debe borrar usuario, no enviarlo por email. Consistencia Wikipedia
🔴 DP Defensive Programming - Proteger ante inputs inesperados Previene crashes, vulnerabilidades En límites del sistema (APIs, inputs) Controladores, funciones públicas Validar inputs, usar defaults seguros, manejar errores explícitamente Wikipedia
🔴 FSD Fail-safe Defaults - Configuración segura por defecto Sistema seguro "out of the box" Al definir configs, permisos Variables de entorno, roles, permisos CORS restrictivo, autenticación ON, logs sin datos sensibles Medium
🟠 RP Robustness Principle (Postel's Law) - Liberal en inputs, estricto en outputs Sistema tolera variaciones pero es predecible En integraciones, APIs APIs, parsers, validadores Aceptar "true", 1, "1" como true. Emitir siempre true (boolean) Wikipedia
🟠 Poka-yoke Diseño que previene errores humanos Reduce errores de uso En UIs, APIs, configs Formularios, CLIs, scripts Validaciones automáticas, confirmaciones para destructivos, tipos fuertes Wikipedia
🔴 AFP Anti-footgun Patterns - Evitar acciones peligrosas sin protección Previene desastres (DELETE sin WHERE) En operaciones destructivas Comandos de admin, migraciones DELETE FROM users → requiere --confirm, dry-run por defecto FreeCodeCamp
🟢 CoC Convention over Configuration - Defaults sensatos Reduce decisiones, acelera desarrollo En frameworks, tooling Estructuras de carpetas, nombres User model → users table automáticamente (Rails, Django) Wikipedia
🟠 CoI Composition over Inheritance - Favorecer composición Evita jerarquías rígidas, aumenta flexibilidad Al reutilizar comportamiento Clases, servicios Inyectar dependencias, usar Strategy/Decorator en vez de herencia profunda Wikipedia
🟠 LoD Law of Demeter - Comunicarse con colaboradores directos Reduce acoplamiento En métodos que usan otros objetos Métodos, servicios Evitar user.account.bank.withdraw(). Exponer user.withdraw() Wikipedia
🟠 TDA Tell, Don't Ask - Indicar acciones, no pedir datos Encapsula lógica en objetos correctos En lógica de negocio Modelos, entidades order.complete() vs if order.status == 'paid': order.status = 'complete' Martin Fowler
🔴 SoC Separation of Concerns - Separar responsabilidades Facilita testing, escalabilidad, mantenimiento En toda arquitectura Capas, módulos UI ≠ Lógica ≠ Persistencia. MVC, Clean Architecture. Ver también Principios de Arquitectura Wikipedia
🟠 GRASP General Responsibility Assignment Software Patterns - Asignar responsabilidades efectivamente Bajo acoplamiento, alta cohesión Al diseñar clases/módulos Clases de dominio Creator, Controller, Information Expert, Low Coupling, High Cohesion Wikipedia
🟢 CUPID Composable, Unix-style, Predictable, Idiomatic, Domain-based Código joyful, productivo En todo desarrollo moderno Todo el código Componentes pequeños, pipeable, sin sorpresas, siguiendo idioms del lenguaje Dan North
🟠 CQS Command-Query Separation - Separar comandos de consultas Claridad sobre efectos secundarios En métodos públicos APIs, métodos getUser() retorna sin modificar. updateUser() modifica sin retornar Martin Fowler
🟠 DIP Dependency Inversion Principle - Depender de abstracciones Facilita testing, intercambio de implementaciones En dependencias entre capas Servicios, repositorios UserService depende de IUserRepository (interfaz), no de implementación concreta. Ver también Principios de Arquitectura Wikipedia
🟢 Hollywood "Don't call us, we'll call you" - Inversión de control Framework orquesta el flujo En frameworks modernos Hooks, callbacks Framework llama a tu código (React useEffect, Angular lifecycle) Martin Fowler
🔴 Arbitrary Precision Evitar la eleccion de precision numerica arbitraria Un error de precisión en un cálculo puede equivaler a un "bug de seguridad o caída" a nivel de negocio En operaciones donde la precision es crítica Operaciones financieras, matematicas de alto nivel Usar BigDecimal en Java, decimal en Python Wikipedia

1.4 🧱 Reglas por Lenguaje

¿Por qué? Cada lenguaje tiene idioms y herramientas específicas que mejoran calidad y productividad.

Lenguaje Qué es Por qué Cuándo Cómo Herramientas de Validación
Python Lenguaje dinámico con tipado opcional Productividad alta, ecosistema rico Backend APIs, scripts, ML/Data Science Usar typing, pydantic para validación, dataclasses para estructuras, mypy para chequeo estático mypy, ruff, black, pylint
Java Lenguaje fuertemente tipado y OOP Robustez, performance, ecosistema enterprise Backend enterprise, Android, sistemas distribuidos Usar Optional evitando null, Streams para colecciones, Records (Java 14+), aplicar SOLID Checkstyle, SpotBugs, SonarQube
TypeScript Superset de JS con tipado estático Detecta errores en compilación, mejor IDE support Frontend, Backend Node.js Usar strict mode, interfaces, tipos utilitarios (Record<K,V>, Partial<T>), evitar any tsc --strict, ESLint, Prettier

1.5 🧩 Reglas por Framework

¿Por qué? Los frameworks establecen patrones que, si se siguen, maximizan productividad y maintainability.

Framework Qué es Por qué Cuándo Cómo Herramientas
Angular Framework frontend con enfoque en componentes y signals Escalabilidad, arquitectura clara, TypeScript nativo SPAs empresariales, dashboards complejos Usar signals (v17+), @for en templates, zoneless rendering, RxJS para async, NgRx para estado, estructura modular Angular CLI, Nx
React Librería para UIs declarativas Flexibilidad, ecosistema gigante, performance SPAs, mobile (React Native), SSR (Next.js) Usar hooks, signals (experimental), context para estado, Suspense para async, Server Components (Next.js), tipado con TS Vite, Next.js, ESLint React
Django Framework Python full-stack con ORM y admin Productividad, "batteries included", comunidad madura Backends complejos, CMS, dashboards admin Usar models, forms, signals, class-based views, DRF para APIs REST. Separar lógica en views, serializers Django Debug Toolbar, pytest-django
FastAPI Framework Python moderno para APIs con tipado fuerte Performance (async), documentación auto (OpenAPI), validación Pydantic APIs REST/GraphQL, microservicios Python Usar Depends para inyección, Pydantic para DTOs, async/await, BackgroundTasks para jobs Uvicorn, SQLAlchemy 2.0
Dash Framework Python para dashboards interactivos Rápido para prototipos analíticos, Python puro Dashboards internos, BI, visualización científica Separar callbacks por módulo, usar dcc.Store para estado, layout modular, evitar callbacks encadenados Plotly, pandas
Spring Boot Framework Java para backend con enfoque microservicios Configuración mínima, ecosistema maduro, production-ready Backend enterprise, microservicios Usar @Service, @Repository, @Entity (JPA), @Validated, DTOs, OpenAPI para docs Spring Actuator, JUnit 5
Spring MVC Framework Java MVC para web Separación clara de responsabilidades Apps web tradicionales, APIs REST Usar @Controller, @RestController, ModelAndView, Thymeleaf para templates, validación en DTOs Spring DevTools

1.5.1 Spring Boot - Features Avanzados

Qué es: Funcionalidades avanzadas de Spring Boot para acelerar desarrollo y mejorar mantenibilidad.

Cuándo: Proyectos empresariales que necesitan auditoría, REST rápido, y tareas batch.

Feature Qué es Cuándo Cómo
@EntityListeners Callbacks en ciclo de vida de entidad Auditoría, validaciones pre-persist @PrePersist, @PreUpdate, @PreRemove, @PostLoad
AuditorAware Auditoría automática global Trackear quién modificó qué Implementar AuditorAware<String>, retornar username actual
@StoredProcedure Llamar stored procedures Lógica compleja en DB, performance @NamedStoredProcedureQuery + @StoredProcedureParameter
Spring Data REST REST APIs automáticas desde repositorios CRUD rápido sin controllers @RepositoryRestResource, @RestResource
@Validated Validación declarativa DTOs, entities @NotNull, @Size, @Email, custom validators
Projections DTOs automáticos para queries Reducir payload, seguridad @Projection, interfaces con getters
Excerpt Projections Proyección por defecto en listas Personalizar respuestas excerptProjection = UserSummary.class
Repository Populator Carga de datos iniciales Seeding, demos JSON/XML en /data, auto-load al arrancar
Spring HATEOAS Hypermedia en APIs RESTful nivel 3, navegación EntityModel, Link, RepresentationModelAssembler
Spring Batch Jobs batch para tareas pesadas Reportes, ETL, migraciones @EnableBatchProcessing, Job, Step, ItemReader/Writer
Specifications API Queries dinámicas type-safe Búsquedas complejas JpaSpecificationExecutor, Specification<T>, Criteria, Predicate
@RepositoryEventHandler Eventos pre/post en repositorios Validaciones, notificaciones @HandleBeforeCreate, @HandleAfterSave
HAL Explorer UI para explorar APIs HATEOAS Testing, documentación interactiva Incluir spring-data-rest-hal-explorer, navegar a /

Ejemplo @EntityListeners:

@Entity
@EntityListeners(AuditingEntityListener.class)
public class User {
    @CreatedDate
    private LocalDateTime createdAt;

    @LastModifiedDate
    private LocalDateTime updatedAt;

    @CreatedBy
    private String createdBy;

    @LastModifiedBy
    private String lastModifiedBy;
}

@Configuration
@EnableJpaAuditing
public class JpaConfig {
    @Bean
    public AuditorAware<String> auditorProvider() {
        return () -> Optional.of(SecurityContextHolder
            .getContext()
            .getAuthentication()
            .getName());
    }
}

Ejemplo Specifications:

// Repository
public interface UserRepository extends JpaRepository<User, Long>, 
                                         JpaSpecificationExecutor<User> {}

// Specification
public class UserSpecifications {
    public static Specification<User> hasEmail(String email) {
        return (root, query, cb) -> 
            cb.equal(root.get("email"), email);
    }

    public static Specification<User> isActive() {
        return (root, query, cb) -> 
            cb.isTrue(root.get("active"));
    }
}

// Uso: búsqueda dinámica
Specification<User> spec = Specification
    .where(hasEmail("user@example.com"))
    .and(isActive());
List<User> users = userRepository.findAll(spec);

Ejemplo Spring Data REST:

@RepositoryRestResource(path = "users", excerptProjection = UserSummary.class)
public interface UserRepository extends JpaRepository<User, Long> {

    @RestResource(path = "by-email", rel = "by-email")
    User findByEmail(@Param("email") String email);
}

// GET /users → lista todos
// GET /users/1 → usuario específico
// POST /users → crear
// GET /users/search/by-email?email=x → custom query

1.6 🎯 Checklist de Código Limpio

Antes de cada commit, verificar:

  • [ ] Nombres de variables/funciones son claros y descriptivos
  • [ ] No hay código comentado (usar control de versiones)
  • [ ] No hay console.log(), print() de debugging
  • [ ] Funciones tienen máximo 30 líneas
  • [ ] Sin magic numbers (usar constantes con nombres)
  • [ ] Tests unitarios para lógica no trivial
  • [ ] Documentación para funciones públicas
  • [ ] Principio de Bajo Acoplamiento y Alta Cohesión respetado
  • [ ] Sin warnings del linter/compiler
  • [ ] Código formateado con herramienta del equipo