Skip to main content

Inicia sesión en CleanKata

Sigue tu progreso, gana XP y desbloquea todas las lecciones.

Al iniciar sesión aceptas nuestros Términos de uso y Política de privacidad.

Código Limpio70 XP7 min

Organización de Clases

Las clases deben ser pequeñas, enfocadas y tener una única razón para cambiar.

Organización Interna

Orden estándar dentro de una clase: (1) constantes estáticas públicas, (2) variables estáticas privadas, (3) variables de instancia privadas, (4) métodos públicos, (5) helpers privados llamados por cada método público, colocados inmediatamente después de él. Esto crea una lectura de arriba abajo: contrato público primero, detalles de implementación abajo.

Orden aleatorio — detalle privado primero

class InvoiceService:
    function _formatAmount(amount):
        return "$" + formatDecimal(amount, 2)

    function _calculateTax(subtotal):
        return subtotal * 0.08

    STANDARD_TAX_RATE = 0.08  // ← buried

    function generate(order):  // ← hard to find
        tax   = _calculateTax(order.subtotal)
        total = order.subtotal + tax
        return "Invoice: " + _formatAmount(total)

Orden estándar — contrato público arriba

class InvoiceService:
    STANDARD_TAX_RATE = 0.08   // 1. constants

    function generate(order):  // 2. public
        tax   = _calculateTax(order.subtotal)
        total = order.subtotal + tax
        return "Invoice: " + _formatAmount(total)

    function _calculateTax(subtotal):  // 3. private helpers
        return subtotal * STANDARD_TAX_RATE

    function _formatAmount(amount):
        return "$" + formatDecimal(amount, 2)

El Principio de Responsabilidad Única

Una clase debe tener una sola razón para cambiar. No un método — una responsabilidad. Pregunta: "Si describo esta clase en una oración, ¿necesita la palabra y?" Si es así, divídela. Un UserManager que maneja autenticación, actualizaciones de perfil, notificaciones por email y logging de auditoría tiene cuatro razones para cambiar. Divídelo en cuatro clases enfocadas.

Clase Dios — hace todo lo relacionado con usuario

class UserManager:
    // Authentication
    function login(email, password): ...
    function logout(sessionId): ...
    function resetPassword(email): ...
    // Profile
    function updateName(userId, name): ...
    function uploadAvatar(userId, file): ...
    // Notifications
    function sendWelcomeEmail(user): ...
    function sendPasswordResetEmail(user): ...
    // Audit
    function logLoginAttempt(email, ok): ...
    function logProfileChange(uid, field): ...

Cuatro clases enfocadas, una razón de cambio cada una

class AuthService:
    function login(email, password): ...
    function logout(sessionId): ...
    function resetPassword(email): ...

class UserProfileService:
    function updateName(userId, name): ...
    function uploadAvatar(userId, file): ...

class UserNotificationService:
    function sendWelcome(user): ...
    function sendPasswordReset(user): ...

class UserAuditLog:
    function recordLogin(email, ok): ...
    function recordProfileChange(uid, field): ...

Cohesión y Cambio

Alta cohesión significa que cada método usa la mayoría de las variables de instancia de la clase. Cuando notas que un grupo de métodos solo usa un subconjunto de las variables de instancia, hay una clase escondida dentro de tu clase — extráela. Las clases deben estar abiertas para extensión, cerradas para modificación: nuevo comportamiento = nueva clase, no editar el código existente.

Baja cohesión — dos clases ocultas en una

class ReportGenerator:
    data   = []      // ─┐ data fields
    source = null    // ─┘
    font   = "Arial" // ─┐ formatting fields
    margin = 20      // ─┘

    function fetchData(): ...   // uses data, source
    function filterData(): ...  // uses data
    function setFont(f): ...    // uses font
    function setMargin(m): ...  // uses margin
    function renderPdf(): ...   // uses font, margin

Alta cohesión — extrae la clase oculta

class DataFetcher:
    source = null
    data   = []

    function fetch(): ...
    function filter(predicate): ...

class PdfRenderer:
    font   = "Arial"
    margin = 20

    function render(data): ...

Desafío de Código

Identifica y Divide la Clase Dios — usa el test del 'y'. Si necesitas 'y' para describirla, divídela.

💡Conclusión clave

Si necesitas 'y' para describir tu clase, tiene más de una responsabilidad. Divídela hasta que cada clase tenga una única razón de existir.

🔧 Algunos ejercicios pueden tener errores. Si algo parece incorrecto, usa el botón Feedback (abajo a la derecha) para reportarlo — nos ayuda a corregirlo rápido.

Pista: Lista cada método de la clase, luego agrúpalos por los datos que operan. Los métodos que solo tocan los mismos campos van juntos. Los grupos que tocan campos *diferentes* te dicen dónde dividir.

✗ Tu versión

Organización de Clases — CleanKata — CleanKata