que-son-poco-y-dto

Qué son POCO y DTOs

  • 5 min

Un POCO es un objeto de dominio limpio y sin dependencias de infraestructura, mientras que un DTO es un objeto pensado para transportar datos entre capas o procesos.

Cuando nos adentramos en arquitecturas de software un poco más complejas (N-Capas, Clean Architecture, Onion), empezamos a ver siglas por todas partes. Dos de las más comunes, y que a menudo se confunden, son POCO y DTO.

¿Son lo mismo? ¿Son solo clases con propiedades? ¿Por qué necesito duplicar mis clases? Vamos a desglosar qué son, de dónde vienen y, sobre todo, cuándo tiene sentido usarlos.

CaracterísticaPOCO (Entidad)DTO
PropósitoLógica de Negocio y EstadoTransporte de datos
Comportamiento(Validaciones, cálculos)No (Solo Get/Set)
PersistenciaMapeado a Base de Datos (ORM)Serializado (JSON/XML)
ContenidoTodos los datos del dominioSolo lo que el cliente necesita

Un POCO modela lo que tu sistema entiende del negocio. Un DTO modela lo que necesitas enviar o recibir.

¿Qué es un POCO?

El término POCO viene de Plain Old CLR Object (en el mundo .NET). En Java se suele hablar de POJO, Plain Old Java Object.

Un POCO es una clase sencilla, pura y sin dependencias de frameworks externos.

Hace años, para usar ciertos frameworks (como versiones antiguas de Entity Framework o Hibernate), tus clases tenían que heredar de clases base extrañas como EntityObject o implementar interfaces complejas. Eso “ensuciaba” tu código.

Un POCO rompe con eso. Es un objeto que solo se preocupa de los datos y la lógica del dominio.

Características de un POCO

  1. Independencia: No hereda de clases de terceros (ni de la base de datos, ni de la UI).
  2. Lógica de Dominio: Puede contener métodos, validaciones y comportamiento propio del negocio.
  3. Persistencia Ignorante: No sabe si se guarda en SQL, en un fichero de texto o en la nube.

Ejemplos

// Un POCO típico (Entidad de Dominio)
public class Usuario
{
    public int Id { get; set; }
    public string Nombre { get; set; }
    public string Email { get; set; }
    public string PasswordHash { get; set; } // Dato sensible
    public DateTime FechaNacimiento { get; set; }

    // ✅ Un POCO puede tener lógica de negocio
    public bool EsMayorDeEdad()
    {
        return DateTime.Now.Year - FechaNacimiento.Year >= 18;
    }
}

Copied!

¿Qué es un DTO?

Un DTO es un Data Transfer Object (Objeto de transferencia de datos). Su definición es mucho más estricta:

Es un objeto cuyo único propósito es transportar datos de un proceso a otro (o de una capa a otra).

A diferencia del POCO, el DTO no debe tener comportamiento. Nada de lógica de negocio, nada de cálculos complejos. Son simples contenedores de datos (“bolsas de propiedades”) con getters y setters.

// Un DTO: Solo datos, nada de lógica
public class UsuarioResumenDTO
{
    public string NombreCompleto { get; set; } // Quizás concatena Nombre + Apellidos
    public string Calle { get; set; }          // Aplanado desde Direccion
    // Fijaos que NO hay Password ni FechaNacimiento
}
Copied!

¿Por qué necesitamos DTOs?

Seguro que estáis pensando: ¿Para qué voy a crear otra clase UsuarioDTO si ya tengo la clase Usuario? ¡Es duplicar código!

Esta es la queja número uno. Pero existen razones de peso (y de seguridad) para hacerlo.

Supongamos que enviáis vuestro objeto Usuario (el POCO) directamente a una API REST para que lo vea el frontend. Ese objeto tiene el campo PasswordHash. ¡Acabas de enviar la contraseña (aunque sea hasheada) a todo internet! 👏

Con un DTO, creas una clase específica UsuarioPublicoDTO que no incluye esa propiedad.

Tu base de datos cambia. Ahora la tabla Usuarios tiene campos nuevos de auditoría interna. Si usas POCOs directamente en tu API, al cambiar la base de datos, rompes el contrato con el cliente.

Usando un DTO, tu base de datos puede cambiar como quiera, siempre que tú mapees los datos correctamente al DTO que espera el cliente.

A veces, un POCO tiene relaciones complejas (Usuario.Pedido.Direccion.Calle). Para una pantalla de resumen, quizás solo quieres el nombre del usuario y la calle. En lugar de enviar un grafo de objetos gigante, creas un DTO plano:

Piensa en el DTO como el paquete de Amazon. El producto real (POCO) está dentro del almacén.

Pero lo que viaja por la carretera es una caja de cartón (DTO) optimizada para el transporte, que protege el contenido y solo lleva la etiqueta necesaria.

El proceso de Mapping

Claro, tener dos clases significa que en algún momento tenemos que pasar los datos de una a otra. A esto se le llama Mapping.

Podemos hacerlo a mano,

public UsuarioDTO Convertir(Usuario u)
{
    return new UsuarioDTO
    {
        Nombre = u.Nombre,
        Email = u.Email
    };
}

Copied!

O podemos usar librerías de Auto-Mapping (como AutoMapper en .NET o MapStruct en Java) que lo hacen automáticamente basándose en los nombres de las propiedades.

Evolución moderna: Records

En lenguajes modernos como C# 9+ o Java 14+, han aparecido los Records. Son el candidato perfecto para los DTOs.

Un record es inmutable por defecto y muy conciso de escribir. Define perfectamente la intención de “esto es solo un dato para transportar”.

// Definición de un DTO usando Records en C#
public record UsuarioDTO(string Nombre, string Email);

Copied!