Nombres, estructura y código al que se puede volver
Nombres
Un nombre dice qué hace la cosa en el lenguaje del dominio, no cómo está implementada. Un nombre que necesita un comentario para entenderse es un mal nombre.
Sé coherente: el mismo término para el mismo concepto en todo el sistema, incluyendo la base de datos y la interfaz. Dos nombres para una cosa son una fuente constante de bugs.
Estructura
Organiza por dominio de negocio y no por tipo de archivo. Una carpeta de 'pedidos' que contiene todo lo relacionado con los pedidos es más fácil de navegar que carpetas separadas por capa.
Mantén los límites: un módulo llega a otro a través de una interfaz definida, no a través de sus partes internas. Los límites mantenidos dentro de un sistema son lo que permite dividirlo después si hace falta.
Simplicidad
Prefiere el código aburrido. Una abstracción creada antes de que hubiera tres casos reales es casi siempre errónea, y más difícil de eliminar que de añadir.
En profundidad
Cuando el código es difícil de probar, casi siempre es señal de una dependencia mezclada con la lógica. En vez de añadir simulaciones, inyecta la dependencia: la prueba se simplifica y la estructura mejora al mismo tiempo, y esa es una de las señales más fiables de un diseño que necesita corrección.