← SEARCHABLE ARCHIVE
C# · 2026-08-12

C# de los fundamentos al dominio — Lección 10

Organizar C# en una estructura de juego comprobable

INTERACTIVE READING MODE →

Los artículos escritos en este blog fueron creados con el objetivo de enseñar. Además, la información del artículo puede ser incorrecta, así que tenga cuidado.

Existe una diferencia entre saber mucha gramática y crear un programa que sea fácil de cambiar. Finalmente, separemos las reglas del juego, guardemos y pantallamos para crear una estructura que se pueda verificar en pequeñas unidades.

Colocar reglas en objetos puros.

public sealed class CombatService
{
    public int CalculateDamage(int attack, int defense)
    {
        return Math.Max(1, attack - defense);
    }

    public void Attack(Character attacker, Character target)
    {
        int damage = CalculateDamage(attacker.Attack, target.Defense);
        target.TakeDamage(damage);
    }
}

Si tus reglas de combate no hacen referencia directa a la interfaz de usuario o a los objetos del motor, puedes usar el mismo código en la consola y en las pruebas. La pantalla sólo es responsable de mostrar resultados y transmitir entradas.

Las funciones externas se colocan detrás de la interfaz.

public interface ISaveStore
{
    Task SaveAsync(SaveData data, CancellationToken token);
    Task<SaveData?> LoadAsync(CancellationToken token);
}

public sealed class GameSession
{
    private readonly ISaveStore saveStore;

    public GameSession(ISaveStore saveStore)
    {
        this.saveStore = saveStore;
    }
}

Al colocar la implementación de su archivo o servidor detrás de una interfaz, puede colocar una implementación falsa para realizar pruebas en lugar de un repositorio real. Esta no es una capa para ocultar la funcionalidad, sino más bien un código de separación de límites que puede cambiar de manera diferente.

Probar la operación

[Fact]
public void DamageNeverDropsBelowOne()
{
    var combat = new CombatService();

    int damage = combat.CalculateDamage(5, 100);

    Assert.Equal(1, damage);
}

La prueba verifica reglas visibles externamente en lugar de simplemente seguir la implementación del método privado. Luego, se puede ver si se mantiene la misma operación incluso si la estructura interna está organizada.

Establecer los límites del motor

En Unity, un MonoBehaviour puede recibir entradas y un ciclo de vida, y un objeto C# normal se puede dividir en responsables de las reglas. Hacer que todas las clases sean MonoBehaviour facilita la conexión al editor, pero la creación y las pruebas están vinculadas al motor.

Una buena estructura no es aquella con una gran cantidad de archivos. Los propietarios del estado, la vida útil de las operaciones asincrónicas, la cancelación de la suscripción a eventos y los límites de los recursos externos están claramente estructurados en el código.

Los tipos, interfaces, genéricos, eventos, LINQ y async de C# no son tecnologías independientes. Es una herramienta que se utiliza en conjunto para dividir piezas cambiables y reducir estados incorrectos.