# Convenciones de Código - Estándares de Desarrollo ## Principios Generales ### Legibilidad - El código se lee más veces de las que se escribe - Usar nombres descriptivos y significativos - Evitar abreviaciones confusas - Comentar el "por qué", no el "qué" ### Consistencia - Seguir las convenciones del equipo/proyecto - Usar herramientas de formateo automático - Mantener estilo uniforme en todo el codebase ### Simplicidad - KISS (Keep It Simple, Stupid) - Evitar sobre-ingeniería - Una función, una responsabilidad - Preferer soluciones simples y claras ## Convenciones por Lenguaje ### Java ```java // Nomenclatura public class UserService { // PascalCase para clases private final UserRepository userRepository; // camelCase para campos private static final int MAX_RETRIES = 3; // SCREAMING_SNAKE_CASE para constantes public Optional findUserById(Long userId) { // camelCase para métodos // Implementación } } ``` ### Python ```python # Nomenclatura PEP 8 class UserService: # PascalCase para clases def __init__(self, user_repository): self.user_repository = user_repository # snake_case para atributos def find_user_by_id(self, user_id): # snake_case para métodos """Encuentra un usuario por ID.""" # docstring descriptivo return self.user_repository.find(user_id) # Constantes MAX_RETRIES = 3 # SCREAMING_SNAKE_CASE ``` ### JavaScript/TypeScript ```javascript // Nomenclatura class UserService { // PascalCase para clases constructor(userRepository) { this.userRepository = userRepository; // camelCase para propiedades } async findUserById(userId) { // camelCase para métodos return await this.userRepository.find(userId); } } const MAX_RETRIES = 3; // SCREAMING_SNAKE_CASE para constantes const userName = 'john_doe'; // camelCase para variables ``` ### C# ```csharp // Nomenclatura public class UserService // PascalCase para clases { private readonly IUserRepository _userRepository; // _camelCase para campos privados private const int MaxRetries = 3; // PascalCase para constantes public async Task FindUserByIdAsync(int userId) // PascalCase para métodos { // Implementación } } ``` ## Estructura de Archivos y Carpetas ### Organización General ``` src/ ├── components/ # Componentes reutilizables ├── services/ # Lógica de negocio ├── models/ # Modelos de datos ├── utils/ # Utilidades generales ├── constants/ # Constantes globales ├── types/ # Definiciones de tipos └── tests/ # Pruebas unitarias/integración ``` ### Nomenclatura de Archivos - **kebab-case**: `user-service.js`, `auth-middleware.js` - **snake_case**: `user_service.py`, `auth_middleware.py` - **PascalCase**: `UserService.cs`, `AuthMiddleware.cs` ## Comentarios y Documentación ### Comentarios Efectivos ```java // ✅ Bueno - Explica el por qué // Usamos cache aquí porque esta operación es muy costosa // y los datos no cambian frecuentemente User cachedUser = userCache.get(userId); // ❌ Malo - Explica lo obvio // Incrementa el contador en 1 counter++; ``` ### Documentación de APIs ```python def calculate_user_score(user_id: int, include_bonus: bool = False) -> float: """ Calcula el score total de un usuario. Args: user_id: ID único del usuario include_bonus: Si incluir puntos bonus en el cálculo Returns: Score total del usuario como float Raises: UserNotFoundException: Si el usuario no existe InvalidScoreException: Si hay datos inconsistentes """ pass ``` ## Manejo de Errores ### Principios - Fallar rápido y dar información útil - Usar excepciones específicas, no genéricas - Log errores con contexto suficiente - No ignorar excepciones silenciosamente ### Ejemplos ```java // ✅ Bueno public User findUser(Long userId) { if (userId == null || userId <= 0) { throw new IllegalArgumentException("User ID must be positive: " + userId); } return userRepository.findById(userId) .orElseThrow(() -> new UserNotFoundException("User not found with ID: " + userId)); } // ❌ Malo public User findUser(Long userId) { try { return userRepository.findById(userId).get(); } catch (Exception e) { return null; // Ignora el error silenciosamente } } ``` ## Testing Conventions ### Nomenclatura de Tests ```java // Patrón: should_ExpectedBehavior_When_StateUnderTest @Test public void should_ReturnUser_When_ValidIdProvided() { // Arrange, Act, Assert } @Test public void should_ThrowException_When_InvalidIdProvided() { // Test implementation } ``` ### Estructura de Tests ```python # Patrón AAA (Arrange, Act, Assert) def test_should_calculate_correct_score_when_valid_user(): # Arrange user_id = 1 expected_score = 85.5 # Act actual_score = score_service.calculate_score(user_id) # Assert assert actual_score == expected_score ``` ## Herramientas de Calidad ### Linters y Formatters - **Java**: CheckStyle, PMD, SpotBugs - **Python**: Black, Flake8, Pylint, mypy - **JavaScript**: ESLint, Prettier - **C#**: StyleCop, ReSharper ### Configuración Ejemplo (.eslintrc.js) ```javascript module.exports = { extends: ['eslint:recommended'], rules: { 'no-unused-vars': 'error', 'no-console': 'warn', 'indent': ['error', 2], 'quotes': ['error', 'single'], 'semi': ['error', 'always'] } }; ```