concepto · fundamentos · 6 min de lectura
Encapsulamiento
El encapsulamiento protege el estado interno de un objeto y expone operaciones controladas para mantener invariantes sin filtrar detalles de implementación.
Antes de leer esto, conviene conocer: Clase.
Alcance en breve
Cubre
- encapsulation as hiding internal state and exposing controlled behavior
- access modifiers, private fields, public methods, invariants, and API boundaries at a conceptual level
- practical trade-offs between direct data access, getters/setters, and intention-revealing methods
No cubre
- language-specific access-control edge cases
- full object-oriented design taxonomy
- security guarantees beyond API-level data hiding
Supone
- The reader understands classes, objects, methods, and basic state mutation.
Resumen
El encapsulamiento es el principio de diseño donde un objeto mantiene sus datos internos bajo control y ofrece una interfaz pública para usarlos de forma segura. En vez de permitir que cualquier parte del sistema cambie cualquier campo, la clase decide qué se puede leer, qué se puede modificar y bajo qué reglas.
Importa porque evita que el resto del código dependa de detalles frágiles. Si todos manipulan el estado directamente, cada cambio interno rompe consumidores y aparecen estados inválidos. Si el objeto encapsula bien, puede cambiar su implementación sin cambiar su contrato público.
Alcance y supuestos
Este paquete cubre encapsulamiento en programación orientada a objetos: estado privado, métodos públicos, invariantes, límites de API y diseño de operaciones con intención. Usa ejemplos en TypeScript, pero el concepto aplica a Java, C#, JavaScript moderno y otros lenguajes con clases u objetos.
No cubre seguridad criptográfica, aislamiento de procesos, módulos avanzados, reflexión, metaprogramación ni todos los detalles de modificadores de acceso de cada lenguaje. Asume que entiendes qué es una clase, una instancia, un atributo y un método.
Modelo mental
Piensa en una máquina expendedora. Desde afuera puedes apretar botones, insertar dinero y recibir un producto. No puedes mover directamente los resortes internos, alterar el contador de stock o abrir la caja de monedas. La máquina expone acciones permitidas y protege sus mecanismos internos para seguir funcionando correctamente.
Un objeto encapsulado funciona igual. Sus campos internos son los mecanismos. Sus métodos públicos son los botones. La regla no es "ocultar por ocultar", sino impedir que el sistema quede en estados imposibles.
El encapsulamiento fuerte responde dos preguntas:
- ¿Qué necesita saber el resto del sistema para usar este objeto?
- ¿Qué detalles deberían poder cambiar sin obligar a todos los consumidores a reescribirse?
Uso práctico
Usa encapsulamiento cuando una entidad tiene reglas que deben mantenerse siempre:
- ✅ Una cuenta bancaria no debería permitir saldo negativo si el dominio no lo permite.
- ✅ Un carrito no debería aceptar cantidades menores o iguales a cero.
- ✅ Un usuario no debería cambiar su email sin validación.
- ❌ No sirve si solo escondes campos y luego generas setters que permiten cualquier valor.
- ❌ No reemplaza validación de seguridad ni autorización; solo define una frontera de uso correcta en el código.
Ejemplo trabajado: proteger el saldo de una cuenta
Una implementación pobre expone el estado y deja que cualquier consumidor lo rompa:
type Account = {
balance: number;
};
const account: Account = { balance: 100 };
account.balance = -500; // estado inválido si la cuenta no permite sobregiro
El problema no es TypeScript. El problema es que el modelo no protege su propia regla. Una versión encapsulada mueve la mutación detrás de operaciones con intención:
class Account {
#balance: number;
constructor(initialBalance: number) {
if (initialBalance < 0) {
throw new Error("Initial balance cannot be negative");
}
this.#balance = initialBalance;
}
getBalance() {
return this.#balance;
}
deposit(amount: number) {
if (amount <= 0) {
throw new Error("Deposit must be positive");
}
this.#balance += amount;
}
withdraw(amount: number) {
if (amount <= 0) {
throw new Error("Withdrawal must be positive");
}
if (amount > this.#balance) {
throw new Error("Insufficient funds");
}
this.#balance -= amount;
}
}
Ahora el resto del sistema no puede escribir balance directamente. Solo puede llamar deposit() o withdraw(), que expresan intención y preservan reglas. Si mañana la cuenta guarda movimientos, comisiones o moneda, la interfaz pública puede mantenerse estable.
El criterio práctico es simple: si un dato tiene reglas de consistencia, no lo expongas como campo libre. Diseña operaciones que mantengan esas reglas cerca del dato.
Evidencia
- Oracle Java Tutorials, Controlling Access to Members of a Class explica cómo los modificadores de acceso controlan si otras clases pueden usar campos o invocar métodos.
- MDN Web Docs, Private elements documenta elementos privados de clases en JavaScript como contraparte de elementos públicos.
- Microsoft Learn, Object-Oriented programming with C# presenta encapsulación como uno de los pilares de OOP junto con abstracción, herencia y polimorfismo.
Conexiones
Requisitos
Requiere
Relacionados y alternativas
Siguiente paso
Relacionado: ComposiciónFuentes citadas
- Oracle Java Tutorials, Controlling Access to Members of a Class (Oficial, 20-07-2026)
- MDN Web Docs, Private elements (Oficial, 20-07-2026)
- Microsoft Learn, Object-Oriented programming with C# (Oficial, 20-07-2026)