Separar métodos que combinan lectura y mutación en dos: un comando (void, con efectos) y una consulta (retorno puro, sin efectos), aplicando el principio Command-Query Separation.
Arrancar un nuevo requerimiento escribiendo un test E2E que atraviesa la frontera del sistema (UI/HTTP) y falla, para guiar outside-in el diseño de la arquitectura desde el exterior hacia el interior.
Reemplazar constructores sobrecargados con métodos fábrica estáticos con nombre semántico, mejorando la expresividad de la creación de objetos y ocultando la lógica de validación.
Reemplazar primitivas (String, int) que representan conceptos de dominio por objetos Value Object inmutables que encapsulan validación, formateo y reglas de negocio asociadas.
Simplificar el arrange de los tests extrayendo la creación de objetos complejos a un Builder fluido, eliminando setUp masivos y datos irrelevantes que lastran la legibilidad.
Aplanar estructuras condicionales anidadas separando los casos límite o inválidos en guard clauses al inicio del método, reduciendo la carga cognitiva y dejando el flujo principal sin anidamiento.
Validar invariantes del sistema generando cientos de casos de prueba aleatorios, descubriendo comportamientos inesperados que los tests basados en ejemplos fijos no cubren.
Eliminar el acoplamiento directo a implementaciones concretas reemplazando la creación interna de dependencias (`new`, estáticos) por parámetros de constructor, aplicando el Dependency Inversion Principle (DIP).