Estructuración de Carpetas en Proyectos de Software
- Mauricio ECR
- Convenciones de código
- 18 Mar, 2025
En proyectos de software de gran escala, la falta de una estructura de carpetas bien definida puede generar desorden, dificultando la mantenibilidad, escalabilidad y comprensión del código. Muchas veces, los proyectos crecen de manera descontrolada sin una estructura definida, lo que lleva a código difícil de navegar, dependencias circulares entre módulos, acoplamiento innecesario entre componentes y dificultad para incorporar nuevos desarrolladores al equipo.
Para estructurar un proyecto de software de manera eficiente, es recomendable seguir una organización de carpetas que refleje claramente la separación de responsabilidades. Esto ayuda a mantener un código modular, organizado y fácil de mantener.
Los principios clave para la organización de carpetas incluyen modularidad, donde cada módulo representa una unidad de negocio independiente; independencia, separando la lógica de negocio de la infraestructura y los adaptadores; cohesión, manteniendo agrupados los elementos relacionados dentro de un módulo; y evolución, permitiendo la escalabilidad sin afectar la estructura global.
Una estructura de carpetas recomendada puede verse de la siguiente manera:
/project-root
├── src
│ ├── core # Reglas de negocio y modelos
│ │ ├── domain
│ │ │ ├── entities
│ │ │ ├── value_objects
│ │ │ ├── repositories
│ │ │ ├── services
│ │ │ └── events
│ │ ├── application
│ │ │ ├── use_cases
│ │ │ ├── dtos
│ │ │ ├── mappers
│ │ │ └── queries
│ ├── modules # Módulos específicos del negocio
│ │ ├── user_management
│ │ │ ├── domain
│ │ │ ├── application
│ │ │ ├── infrastructure
│ │ │ ├── adapters
│ ├── infrastructure # Implementaciones técnicas y frameworks
│ │ ├── persistence
│ │ ├── messaging
│ │ ├── external_services
│ │ ├── config
│ ├── adapters # Interfaces externas y controladores
│ │ ├── api
│ │ ├── cli
│ │ ├── event_consumers
│ │ └── schedulers
├── tests # Pruebas unitarias y de integración
├── docs # Documentación del proyecto
├── scripts # Herramientas para automatización
├── config # Configuración general del proyecto
├── .gitignore
├── README.md
Dentro de esta estructura, ‘core/’ contiene la lógica de negocio (entidades, servicios, repositorios, etc.); ‘modules/’ agrupa los módulos del dominio de manera aislada; ‘infrastructure/’ contiene implementaciones técnicas como bases de datos, servicios externos y configuraciones; ‘adapters/’ define las interfaces de comunicación con el mundo exterior, incluyendo APIs, CLI y eventos; ‘tests/’ contiene pruebas unitarias e integración; ‘docs/’ almacena documentación técnica del proyecto; ‘config/’ centraliza archivos de configuración; y ‘scripts/’ incluye herramientas de automatización.
Por ejemplo, en un sistema de gestión de usuarios con autenticación, podríamos estructurar el módulo correspondiente de la siguiente manera:
/modules/user_management
├── domain
│ ├── entities
│ │ ├── UserEnt.ts
│ ├── value_objects
│ │ ├── EmailVO.ts
│ ├── repositories
│ │ ├── UserRepo.ts
├── application
│ ├── use_cases
│ │ ├── RegisterUserUC.ts
│ │ ├── AuthenticateUserUC.ts
│ ├── dtos
│ │ ├── UserDTO.ts
│ ├── mappers
│ │ ├── UserMap.ts
├── infrastructure
│ ├── persistence
│ │ ├── UserRepoImpl.ts
├── adapters
│ ├── api
│ │ ├── UserCtrl.ts
Aquí, la capa de dominio maneja las reglas de negocio, la capa de aplicación contiene los casos de uso, la infraestructura gestiona la persistencia y los adaptadores exponen las funcionalidades a través de controladores API.
Resumen de Carpetas y su Uso
| Carpeta | Descripción | Ejemplo en ‘user_management' |
|---|---|---|
| 'core/domain’ | Contiene entidades, objetos de valor, repositorios y servicios | ’UserEnt.ts’ define la entidad de usuario |
| ’core/application’ | Define casos de uso, DTOs, mappers y queries | ’RegisterUserUC.ts’ implementa la lógica de registro de usuario |
| ’modules’ | Agrupa módulos específicos del negocio | ’user_management/’ encapsula toda la gestión de usuarios |
| ’domain/entities’ | Modelos de negocio que representan objetos persistentes | ’UserEnt.ts’ representa los datos del usuario en la base de datos |
| ’domain/value_objects’ | Objetos de valor inmutables del dominio | ’EmailVO.ts’ maneja la lógica del correo electrónico |
| ’domain/repositories’ | Interfaces para acceso a datos | ’UserRepo.ts’ define la interfaz para obtener usuarios |
| ’application/use_cases’ | Casos de uso que orquestan la lógica de negocio | ’RegisterUserUC.ts’ contiene la lógica de registro de usuario |
| ’application/dtos’ | Transporte de datos entre capas | ’UserDTO.ts’ define el formato de los datos de usuario |
| ’application/mappers’ | Conversión entre entidades y DTOs | ’UserMap.ts’ convierte entre ‘UserEnt’ y ‘UserDTO' |
| 'infrastructure/persistence’ | Implementación de acceso a datos | ’UserRepoImpl.ts’ implementa ‘UserRepo.ts' |
| 'adapters/api’ | Exposición de funcionalidades vía API | ’UserCtrl.ts’ maneja solicitudes HTTP |
| ’tests’ | Contiene pruebas unitarias y de integración | ’UserSvcTest.ts’ prueba ‘RegisterUserUC.ts' |
| 'docs’ | Documentación técnica del proyecto | Documentación sobre el flujo de autenticación |
| ’config’ | Configuración general de la aplicación | Configuración de base de datos y variables de entorno |
| ’scripts’ | Scripts de automatización | Scripts para migraciones o configuración |
Implementar una estructura de carpetas bien organizada ayuda a crear proyectos más mantenibles, escalables y fáciles de entender. Al separar claramente las responsabilidades, evitamos el acoplamiento innecesario y mejoramos la colaboración dentro del equipo de desarrollo. Desde el inicio del proyecto, es recomendable definir y documentar la estructura de carpetas para que todo el equipo la adopte y mantenga. Con esta estructura clara y modular, los proyectos de software pueden escalar sin comprometer la calidad del código. 🚀