Jugar con código: un enfoque ágil y eficiente (Español (Spanish))

Jugar con código: un enfoque ágil y eficiente

Sunday, 23 November 2025

//

21 minute read

¿Por qué tratar su rama como una caja de arena —y jugar como trabajo legítimo— produce un mejor software con menos estrés.

Toma caliente: La mayoría de los desarrolladores están tratando de ser perfectos en cada etapa del desarrollo, y está matando tanto su creatividad y su productividad.

Introducción

He estado construyendo software profesionalmente para... bueno, digamos que recuerdo cuando "Agile" era una idea nueva y no una palabra de moda corporativa armada por los gerentes de proyecto para justificar más standups.

A lo largo de los años, he notado algo: el mejor código que he escrito vino de proyectos donde me sentí permiso para jugar. El peor código vino de proyectos donde cada pulsación de teclas se sentía como si estuviera siendo escrutado, donde yo estaba tratando de escribir código "listo para la producción" desde el minuto uno.

Esto no es accidental. La creatividad y la presión no se mezclan bien.

Así que he desarrollado un enfoque que separa la exploración desordenada y creativa de la entrega pulida y lista para la producción.Haz que funcione, hazlo bonito, enciérralo.- pero en realidad, se trata de darte permiso para experimentar sin el peso de la perfección que cuelga sobre ti.

Las tres fases

Permítanme ser claro por adelantado: esto no se trata de ser descuidado o evitar la disciplina. Se trata de aplicar la disciplina adecuada en el momento adecuado.

graph LR
    subgraph "Phase 1: Make It Work"
        A[New Requirement] --> B[Explore & Experiment]
        B --> C{Does It Work?}
        C -->|No| D[Try Different Approach]
        D --> B
        C -->|Yes| E[Basic Solution]
    end

    subgraph "Phase 2: Make It Pretty"
        E --> F[Refactor & Clean]
        F --> G[Apply SOLID Pragmatically]
        G --> H[Get Stakeholder Feedback]
        H --> I[Polished Solution]
    end

    subgraph "Phase 3: Lock It Down"
        I --> J[Add Tests]
        J --> K[Security Review]
        K --> L[Add Monitoring]
        L --> M[Production Ready]
    end

    style A stroke:#f59e0b,stroke-width:3px
    style E stroke:#0ea5e9,stroke-width:3px
    style I stroke:#8b5cf6,stroke-width:3px
    style M stroke:#10b981,stroke-width:4px

Fase 1: Hacer que funcione

El mantra: Jueguen primero, confirmen sus suposiciones, hagan que algo funcione.

Esta es la fase en la que tu rama es una caja de arena. El código desordenado está bien. Los extremos muertos están bien. *Bien.*No estás construyendo una catedral aquí, estás dibujando en una servilleta.

Lo que intentas averiguar:

  • ¿Esta API realmente se comporta como afirman los docs? (Spoiler: rara vez lo hace)
  • ¿Puedo incluso resolver este problema con las herramientas que tengo?
  • ¿Cuáles son los requisitos reales, no los escritos en el billete?
  • ¿Es un problema de dos horas o un problema de dos semanas?

La visión crítica: Hasta que levantas una RRPP, tu sucursal es el tuyo. Es tu laboratorio experimental. Nadie necesita ver tus inicios falsos, tu código de depuración comentado, tus comentarios "TODO: esto es terrible, arregla después". Pero revisa OFTEN, cada vez que tengas algo que funcione, te comprometas y empujes. Engancha en tu tubería CI; una buena tubería te dará más información (pruebas de integración, romper cambios en otros lugares, etc.). Está bien comprobar en feo, apenas cosido código franken. Ese es el punto. Incluso como veterano de tres décadas, sigo haciendo esto. Libera mi mente.

Prestación complementaria: Los compromisos frecuentes son un latido del corazón. En equipos remotos/sincronizados, un rastro constante de compromisos "feos pero progresivos" tranquiliza a todos los que trabajan en movimiento, sin que tengas que realizar productividad en Slack.

Esta libertad psicológica es esencial. Cuando sabes que puedes tirar todo y empezar de nuevo, tomas decisiones más audaces. Intentas ese enfoque extraño que probablemente no funcionará. A veces funciona brillantemente. A veces necesitas leer un artículo, ver un video de YouTube, pensar por un tiempo. Recuerda: tu trabajo es entregar un buen software y buenas decisiones, no escribir rápido. NO UN TIPISTA.

// Phase 1 code looks like this - and THAT'S OKAY
public async Task<Result> ProcessThing(Request req)
{
    // TODO: what if this is null?
    var data = await _api.GetSomething(req.Id);

    // This probably isn't right but let's see what happens
    var transformed = data.Items
        .Where(x => x.Status != "deleted") // Is this the right filter?
        .Select(x => new Thing { Name = x.Name }); // Missing loads of fields

    // HACK: hardcoded for now
    return new Result { Items = transformed.ToList(), Total = 42 };
}

¿Es este código de producción? Dios no. ¿Es útil? Absolutamente. Te dice si tu enfoque es incluso viable antes de invertir horas puliendo algo que no funcionará.

Una nota sobre la retroalimentación: Usted puede obtener comentarios en cualquier punto en la Fase 1: la clave es elegir quién El objetivo es construir la mejor característica, no seguir un proceso rígido.

¿Construir una API que otro equipo consumirá? Involucrarlos temprano. Una conversación rápida "¿tiene sentido esta forma?" puede ahorrar días de retrabajo. ¿Construir algo orientado al usuario? Tal vez no mostrar a la parte interesada del negocio hasta que sea menos áspero — algunas personas se cuelgan de cómo algo Mira. más bien que si se trata de obras. Eso está bien; dan retroalimentación en la Fase 2.

Usa tu juicio. A veces necesitas retroalimentación para aclarar, no aprobar —la especificación ya lo hizo. "La especificación dice 'errores de mano con gracia'— significa reintentar tres veces, o fallar rápido y notificar?" Esa es una conversación de Fase 1.

Si la entrada de un stakeholder es crítica pero que lucharía con el código bruto, construir una demo trivial. Un hardcoded happy-path que muestra el concepto puede desbloquear valiosa retroalimentación sin la distracción de los casos de borde faltante.

Ser pragmático. El objetivo es la mejor característica, no la pureza del proceso.

Fase 2: Hacerlo bonito

El mantra: Ahora que sabes lo que estás construyendo, hazlo Bien..

La fase exploratoria ha hecho su trabajo. Usted ha confirmado que el enfoque funciona, usted entiende la forma del problema, y probablemente ha descubierto una docena de casos de borde que el boleto original no mencionó.

Ahora límpialo:

// Phase 2: Same logic, but actually maintainable
public async Task<ProcessingResult> ProcessItemsAsync(
    ProcessingRequest request,
    CancellationToken cancellationToken = default)
{
    ArgumentNullException.ThrowIfNull(request);

    var items = await _itemRepository.GetActiveItemsAsync(
        request.AccountId,
        cancellationToken);

    var processedItems = items
        .Where(item => item.Status != ItemStatus.Deleted)
        .Select(item => _mapper.ToProcessedItem(item))
        .ToList();

    return new ProcessingResult
    {
        Items = processedItems,
        TotalCount = processedItems.Count,
        ProcessedAt = _timeProvider.UtcNow
    };
}

Aquí es donde:

  • Aplicar los principios SOLID pragmaticalmente (Conócelos, pero no los adores)
  • Dar nombres propios a las cosas
  • Añadir sugerencias de tipo y documentación XML
  • Piense en la superficie de la API desde la perspectiva de la persona que llama
  • Maneje los casos de borde que descubrió en la Fase 1

Críticamente, este es el mejor momento para la retroalimentación de partes interesadas no técnicas. La función es ahora visible y utilizable, pero todavía no has invertido horas de pruebas de escritura para ello. Si dicen "en realidad, queríamos que hiciera X en su lugar", se puede pivotar sin el corazón roto de eliminar una suite de pruebas completa.

Fase 3: Bloquearlo

El mantra: Endurécelo, pruébalo, hazlo resistente.

Ahora, y sólo ahora, usted escribe sus pruebas. Añada comprobaciones de seguridad. Implemente el manejo adecuado de errores para casos de borde de producción. Añada monitoreo y barandillas de seguridad.

¿Por qué esperar hasta ahora? Por fin sabes lo que estás probando..

Las pruebas escritas en la Fase 1 hubieran sido incorrectas; aún no entendías el problema. Las pruebas escritas en la Fase 2 habrían sido muy duras; todavía estabas refinando la API. Las pruebas escritas en la Fase 3 son: correcto, porque la aplicación es estable.

[Theory]
[InlineData(0)]
[InlineData(1)]
[InlineData(100)]
public async Task ProcessItemsAsync_WithValidRequest_ReturnsCorrectCount(
    int itemCount)
{
    // Arrange
    var items = _fixture.CreateMany<Item>(itemCount).ToList();
    _mockRepository
        .Setup(r => r.GetActiveItemsAsync(It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
        .ReturnsAsync(items);

    // Act
    var result = await _sut.ProcessItemsAsync(
        new ProcessingRequest { AccountId = Guid.NewGuid() });

    // Assert
    result.TotalCount.Should().Be(itemCount);
    result.Items.Should().HaveCount(itemCount);
}

[Fact]
public async Task ProcessItemsAsync_WithNullRequest_ThrowsArgumentNullException()
{
    // Act & Assert
    await _sut.Invoking(s => s.ProcessItemsAsync(null!))
        .Should().ThrowAsync<ArgumentNullException>();
}

[Fact]
public async Task ProcessItemsAsync_ExcludesDeletedItems()
{
    // Arrange
    var items = new[]
    {
        new Item { Status = ItemStatus.Active },
        new Item { Status = ItemStatus.Deleted },
        new Item { Status = ItemStatus.Active }
    };
    _mockRepository
        .Setup(r => r.GetActiveItemsAsync(It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
        .ReturnsAsync(items);

    // Act
    var result = await _sut.ProcessItemsAsync(
        new ProcessingRequest { AccountId = Guid.NewGuid() });

    // Assert
    result.Items.Should().HaveCount(2);
}

Esta fase incluye también:

  • Revisión de seguridad (autenticación, autorización, validación de entrada)
  • Consideraciones de concurrencia (¿qué sucede bajo carga?)
  • Análisis del modo de fallo (¿qué pasa si la base de datos es lenta? ¿Qué pasa si la API se apaga?)
  • Monitoreo (¿cómo sabremos si esto se rompe en la producción?)

Coreografía de retroalimentación

Distintas personas deberían estar involucradas en diferentes etapas. Entiéndelo mal y te ahogarás en la fricción.

graph TB
    subgraph "Phase 1: Technical Voices"
        P1[Make It Work] --> T1[Senior Dev Review]
        T1 --> T2["Does the approach<br/>make sense?"]
        T2 --> T3["Any obvious<br/>architectural issues?"]
    end

    subgraph "Phase 2: Non-Technical Voices"
        P2[Make It Pretty] --> N1[Product Owner Demo]
        N1 --> N2["Does it meet<br/>the requirement?"]
        N2 --> N3["Is the UX<br/>intuitive?"]
    end

    subgraph "Phase 3: Ops/Security Voices"
        P3[Lock It Down] --> O1[Security Review]
        O1 --> O2[Operations Review]
        O2 --> O3["Will it hold up<br/>in production?"]
    end

    T3 --> P2
    N3 --> P3

    style T1 stroke:#3b82f6,stroke-width:2px
    style N1 stroke:#8b5cf6,stroke-width:2px
    style O1 stroke:#ef4444,stroke-width:2px

Fase 1: Solo voces técnicas —devs superiores, arquitectos. Pueden ver más allá del desorden a la forma de la solución. Los interesados no técnicos entrarán en pánico con el código rudo y preguntarán sobre los colores de los botones cuando aún estés averiguando el modelo de datos.

Fase 2: Las voces no técnicas son bienvenidas. La función es utilizable, los botones hacen cosas. Haga que los propietarios de productos y los diseñadores se involucren ahora: los cambios siguen siendo baratos, todavía no has escrito pruebas.

Fase 3: Operaciones y voces de seguridad. "¿Qué pasa si esto consigue tráfico 10x?" "¿Qué pasa si alguien pasa entrada maliciosa?" Estas preocupaciones sólo importan una vez que la característica realmente funciona.

Ramas como cajas de arena

Esto es lo que cambió mi vida de desarrollo: hasta que usted levanta una RRPP, su sucursal es totalmente privada.

Eso puede sonar obvio, pero veo a los desarrolladores tratando a cada comisión como si fuera a su registro permanente, tienen miedo de experimentar, miedo de escribir un código feo, miedo de romper cosas.

Quiero que pienses en tu rama como una caja de arena, un patio de recreo, un laboratorio donde se esperan explosiones y nadie salga herido.

graph TD
    A[Feature Branch Created] --> B[Experiment Freely]
    B --> C{Did it work?}
    C -->|No| D[Try Something Else]
    D --> B
    C -->|Yes| E[Clean Up the Mess]
    E --> F[Interactive Rebase]
    F --> G[Squash to Clean Commits]
    G --> H[Raise PR]
    H --> I[Public Code Review]

    style B stroke:#f59e0b,stroke-width:3px
    style D stroke:#f59e0b,stroke-width:2px
    style H stroke:#10b981,stroke-width:3px

    subgraph "Private - Go Mental"
        B
        C
        D
        E
    end

    subgraph "Public - Be Professional"
        H
        I
    end

En la práctica, esto significa:

  • Comprometerse con frecuencia, incluso si el código no se compila
  • Escribir FIXME y TODO comentarios en todas partes
  • Deje el código de depuración en su lugar mientras está explorando
  • Tener múltiples "probar este enfoque" confirma
  • No te preocupes por los mensajes de confirmación (vas a aplastar más tarde)

Entonces, antes de levantar una RRPP:

  1. Limpiar el código (Fase 2)
  2. Añadir pruebas (Fase 3)
  3. Rebase interactivo para aplastar toda esa historia desordenada
  4. Escriba un mensaje de confirmación adecuado

Los revisores de PR ven código profesional limpio con una narrativa clara. Ellos no ven los seis inicios falsos, el 3am "por qué no este trabajo sangriento" compromete, o la historia de "deshacer deshacer".

La caja de arena se mantiene privada. El trabajo pulido se hace público.

Por qué esto reduce el estrés

El desarrollo tradicional de "ser profesional en todo momento" es aplastante. Cada línea se siente permanente. Cada decisión se siente consecuente. Este enfoque elimina esa presión al contener el caos: el juego es trabajo legítimo En la Fase 1, la retroalimentación llega cuando el pivote es barato en la Fase 2, y las pruebas se escriben una vez correctamente en la Fase 3 porque finalmente sabes lo que estás probando.

"El juego es un trabajo legítimo".

TDD funciona brillantemente cuando el dominio es bien entendido o usted está fijando un bug conocido. Pero cuando el problema es todavía borroso, las pruebas de escritura primero a menudo significa probar la cosa incorrecta tres veces seguidas. Este enfoque elude que: explorar primero, probar cuando es estable.

Prágmático SOLID (y el sucio secreto de DRY)

Entonces, ¿qué hace esta mentalidad trifásica a sus principios de diseño? En resumen: mata el dogma. Así es como cambia mi pensamiento sobre SOLID, DRY, e interfaces en C#.

Mencioné la aplicación de principios SOLID "pragmáticamente" en la Fase 2.

SOLID es un buen conjunto de principios. Yo les enseño. Yo los uso. Pero he visto a los equipos desaparecer por los agujeros de conejo abstracción en nombre de la Responsabilidad Única o Abierto/Cerrado, creando sistemas tan flexibles que son incomprensibles.

Aquí está mi heurística:

Aplicar SOLID cuando:

  • Tienes pruebas de que necesitarás flexibilidad.
  • La abstracción hace el código más claro
  • Estás construyendo algo que otros usarán.

No aplique SOLID cuando:

  • Usted está especulando sobre los requisitos futuros
  • La abstracción añade complejidad sin claridad
  • Usted está construyendo código interno que sólo usted mantiene

Tres líneas de código similares son mejores que una abstracción prematura. Siempre se puede extraer más tarde cuando se ve el patrón claramente. No se puede deshacer fácilmente una abstracción que se cuece en su arquitectura.

// Over-engineered SOLID worship
public interface IThingProcessor { }
public interface IThingProcessorFactory { }
public class ThingProcessorFactory : IThingProcessorFactory { }
public class ThingProcessor : IThingProcessor { }
public class ThingProcessorDecorator : IThingProcessor { }
public class ThingProcessorValidationDecorator : IThingProcessor { }

// What you probably actually need
public class ThingProcessor
{
    public async Task<Result> ProcessAsync(Thing thing)
    {
        // Just do the thing
    }
}

Si necesita la flexibilidad más tarde, la refactorización es barata. La sobreingeniería por adelantado es costosa porque está manteniendo capas de abstracción que no se están ganando su sustento.

La trampa seca

Y mientras matamos vacas sagradas, hablemos de SECAS Es quizás el principio más dogmaticamente aplicado en nuestra industria, y cuando se aplica sin pensar, causa más daño que bien.

El problema es el siguiente: no toda duplicación es el mismo tipo de duplicación.

Cuando dos piezas de código se ven similares pero sirven a diferentes propósitos, extrayéndolas en una abstracción compartida parejas cosas que deben evolucionar de forma independiente. Ahora, cuando un caso de uso necesita cambiar, usted es:

  1. Añadir parámetros y condicionales para manejar ambos casos (lo que empeora la abstracción)
  2. Rompiendo el otro caso de uso
  3. Copiar el código compartido y editarlo (admitir DRY fue incorrecto aquí)
// "DRY" solution - looks clever, causes pain
public async Task<Result> ProcessEntity<T>(
    T entity,
    bool validateFirst = true,
    bool sendNotification = false,
    Func<T, bool>? customFilter = null,
    Action<T>? preProcess = null,
    Action<T>? postProcess = null) where T : IEntity
{
    // 50 lines of conditional spaghetti trying to handle
    // "processing" for Users, Orders, and Products
    // because they all had 3 similar lines once
}

// What you probably actually need
public async Task<Result> ProcessUser(User user) { /* 15 clear lines */ }
public async Task<Result> ProcessOrder(Order order) { /* 15 clear lines */ }
public async Task<Result> ProcessProduct(Product product) { /* 15 clear lines */ }

Sí, hay una "duplicación" en el segundo enfoque, pero cada método es:

  • Fácil de entender aisladamente
  • Fácil de modificar sin efectos secundarios
  • Fácil de borrar cuando ese tipo de entidad desaparece
  • Fácil de probar con entradas y salidas claras

La versión DRY es una pesadilla para mantener porque está tratando de ser todas las cosas para todos los que llaman. Cada cambio requiere entender todos los casos de uso. Cada corrección de errores se arriesga a romper algo más.

Mi regla: Tolerar la duplicación hasta que hayas visto la igual tres veces y estás seguro de que representa la igual Hasta entonces, un poco de pasta-copia está bien. No es una falla moral; es la precaución apropiada.

La duplicación es mucho más barata que la abstracción equivocada. Siempre se puede deduplicar más tarde cuando el patrón es claro. No se puede deshacer fácilmente una mala abstracción que está tejida a través de su base de código.

El problema de interfaz en C#

Aquí hay otra vaca sagrada que necesita ser sacrificada: el patrón "cada clase necesita una interfaz".

En los primeros días de la inyección de dependencia de .NET, alguien decidió que para que el código fuera testable, necesitabas inyectar interfaces en todas partes. La lógica era: no puedes burlarte de una clase concreta, así que cada servicio necesita IService y ServiceImpl. De repente, cada base de código C# estaba llena de interfaces de implementación única que existían exclusivamente para las pruebas.

// The interface tax - early 2010s style
public interface IUserService { }
public interface IOrderService { }
public interface IEmailService { }
public interface INotificationService { }
public interface IPaymentProcessor { }
public interface IInventoryManager { }

// Each with exactly ONE implementation
public class UserService : IUserService { }
public class OrderService : IOrderService { }
// ... you get the idea

Esto era programación de culto de carga. Estábamos pagando un impuesto de complejidad para teórica la capacidad de ensayo y teórica flexibilidad futura que rara vez se materializó.

Esta es la cosa: ya no necesitas esto.

Marcos modernos de burla como NSubstitute y Moq Más importante aún, el contenedor DI de ASP.NET Core funciona perfectamente con tipos de hormigón:

// Modern approach - just register the concrete type
services.AddScoped<UserService>();
services.AddScoped<OrderService>();
services.AddScoped<EmailService>();

// In your controller or service
public class OrderController(OrderService orderService, UserService userService)
{
    // Primary constructor injection - clean and simple
}

No hay interfaces. IOrderServiceSólo el servicio que necesitas, inyectado directamente.

"¿Pero qué pasa con las pruebas?" Te oigo llorar.

Para las pruebas unitarias, usted tiene opciones:

  1. Hacer métodos clave virtual y utilizar un marco de burla
  2. Utilice el servicio real con una base de datos de pruebas (las pruebas de integración son a menudo más valiosas de todos modos)
  3. Añadir una interfaz cuando realmente lo necesitas para las pruebas

Este tercer punto es crucial: herramientas de refactorización son extraordinariamente buenos en la extracción de interfaces.

En Rider o Visual Studio, es literalmente Ctrl+. → "Extraer interfaz" y ya está hecho. Cada método se extrae, la clase se actualiza para implementarlo, y puede encontrar/reemplazar todos los usos si es necesario. Toma segundos.

// Phase 1 & 2: Just write the class
public class OrderService
{
    public async Task<Order> CreateOrderAsync(CreateOrderRequest request) { ... }
    public async Task<Order?> GetOrderAsync(int orderId) { ... }
    public async Task CancelOrderAsync(int orderId) { ... }
}

// Phase 3: Need to mock it for testing? Extract interface in 2 seconds
public interface IOrderService
{
    Task<Order> CreateOrderAsync(CreateOrderRequest request);
    Task<Order?> GetOrderAsync(int orderId);
    Task CancelOrderAsync(int orderId);
}

public class OrderService : IOrderService { ... }

Mi flujo de trabajo ahora: Las interfaces vienen en la Fase 3, no en la Fase 1..

Durante "hacerlo funcionar" y "hacerlo bonito", sólo escribo clases. Sin abstracción prematura. No hay impuesto de interfaz en cada tipo. El código es más simple, más fácil de navegar (no saltar entre IFoo y Foo), y más rápido para escribir.

Cuando golpeo "bloquearlo" y necesito escribir pruebas, entonces Yo decido qué servicios realmente necesitan burlarse. Usualmente es menos de lo que uno pensaría, a menudo sólo integraciones externas como clientes HTTP, bases de datos y colas de mensajes.

Para los servicios internos de lógica de negocios? La mitad de las veces los pruebo directamente con dependencias reales. Las pruebas son más valiosas de todos modos porque prueban el comportamiento real, no una burla de lo que I Piensa el comportamiento debe ser.

// Services I typically DO extract interfaces for (external boundaries)
public interface IPaymentGateway { }      // Third-party API
public interface IEmailSender { }         // External service
public interface IBlobStorage { }         // Cloud storage

// Services I typically DON'T need interfaces for (internal logic)
public class OrderValidator { }           // Pure logic, test directly
public class PriceCalculator { }          // Pure logic, test directly
public class OrderService { }             // Test with real repo + in-memory DB

El punto es: Deje de escribir interfaces por adelantado "por si acaso". Escriba clases de concreto. Si necesita una interfaz para probar o polimorfismo genuino más tarde, extraer una toma literalmente segundos con herramientas modernas.

Su base de código será más simple, más navegable, y no tendrá la carga de mantenimiento de mantener las interfaces en sincronización con las implementaciones sin ningún beneficio.

La conexión ágil

Irónicamente, este enfoque está más alineado con el original Manifiesto ágil que la mayoría de los procesos "Agiles" que he encontrado. Software de trabajo rápido (Fase 1). Responder al cambio (Fase 1-2). Colaboración con el cliente cuando la característica es demostrable (Fase 2). Sin puntos de sprint, sin seguimiento de velocidad, sin gráficos de quemaduras sangrientas.

El "Agile" moderno ha sido capturado por entusiastas del proceso que han añadido tantas ceremonias que no hay tiempo para la exploración.Este enfoque trae de vuelta el juego, no como una indulgencia, sino como una fase legítima del trabajo creativo.

Cuándo NO usar este enfoque

Debería ser honesto: este no es siempre el enfoque correcto.

Corrección de errores: Cuando estás arreglando un bug conocido, el estilo TDD tiene más sentido. Escribe una prueba que reproduzca el bug, arreglalo, hecho.

Problemas bien entendidos: Si estás implementando un algoritmo estándar o un patrón que has usado cien veces, no necesitas una fase de exploración.

Plazos estrictos con requisitos conocidos: Si realmente sabes exactamente lo que estás construyendo y cuando necesita enviar, podrías saltarte la exploración de la Fase 1.

Entornos altamente regulados: Si cada comisión necesita firmar, el sandboxing es más difícil. Aunque usted todavía puede hacer la exploración local antes de empujar.

Pero para la mayoría desarrollo de características —donde los requisitos son un poco confusos, el enfoque técnico no es obvio, y necesitas espacio para pensar— este enfoque funciona brillantemente.

Una nota para desarrolladores jóvenes

Si llegas temprano en tu carrera, es posible que sientas presión para mostrar código "perfecto" todo el tiempo. No tienes que hacerlo. Usa este enfoque de tres fases, sólo tienes que tener claro en qué fase estás, y siempre termina el trabajo hasta la fase 3. Nadie te culpará por un código de exploración desordenado si conduce a un código pulido, probado y listo para la producción al final.

Conclusión

Hacer que funcione, hacerlo bonito, cerrarlo.

Comience simple. Diseño con previsión, pero no especulación. Iterar rápidamente. Sólo añadir complejidad cuando vale la pena.

"La duplicación es mucho más barata que la abstracción equivocada".

La fase de exploración no es un secreto culpable, es una parte definida del proceso. Su rama es su caja de arena hasta que se levanta una RRPP. La retroalimentación técnica llega temprano, la retroalimentación no técnica llega a mediados, las operaciones y la retroalimentación de seguridad llega tarde.

Esto mantiene viva la creatividad, reduce el estrés y produce sistemas que escalan elegantemente, porque usted entendió el problema antes de comprometerse con la solución.

Deja de tratar de ser perfecto desde el primer minuto, date permiso para jugar.


Lectura relacionada

Si esto resuena, también puede disfrutar de estos posts relacionados:

Finding related posts...
logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.