JS: Abstracción de datos

Teoría: Interfaces

En TI, el término "Interfaz" es ampliamente utilizado y se asemeja al uso que le damos en la vida cotidiana. Por ejemplo, la interfaz de usuario es un conjunto de elementos de control en un sitio web, un cajero automático, un teléfono, etc. Los botones son la interfaz del control remoto del televisor. Todos los controles y botones de un automóvil también son su interfaz. En resumen, la interfaz define la forma en que interactuamos con un sistema.

Crear interfaces de calidad no es tan fácil como parece a primera vista. Diría que es extremadamente difícil. Todos los días nos encontramos con interfaces incómodas, desde la forma en que se abren las puertas hasta el funcionamiento de los ascensores. Cuanto más complejo es un sistema (es decir, cuantos más estados posibles tiene), más difícil es diseñar la interfaz. Incluso en un ejemplo simple como el botón de encendido de un televisor (dos estados: encendido/apagado), se puede implementar con dos botones o con uno solo que se comporte de manera diferente según el estado actual.

La programación funciona de manera similar. Una interfaz se refiere a un conjunto de funciones (nombres y firmas, es decir, la cantidad y tipos de parámetros de entrada, así como el valor de retorno) que no dependen de una implementación específica. Esta definición coincide exactamente con el concepto de tipo de dato abstracto. Por ejemplo, para los puntos, todas las funciones que hemos implementado en la práctica y que se describen en la teoría son interfaces.

¿Cómo se relacionan los conceptos de abstracción e interfaz? La abstracción es un término que describe principalmente los datos con los que trabajamos. Por ejemplo, casi todas las aplicaciones web incluyen la abstracción de "usuario". En Códica, hay la abstracción de "curso", "proyecto" y muchas otras. La interfaz, por otro lado, se refiere a un conjunto de funciones con las que se puede interactuar con los datos.

Sin embargo, las funciones no solo pueden ser interfaces, también pueden ser auxiliares y no están destinadas al código que las llama, sino que se utilizan exclusivamente dentro de la abstracción:

// Las funciones makeUser, getAge, isAdult son la interfaz de la abstracción User.
// Se utilizan en el código externo (del usuario, que las llama).
const makeUser = (name, birthday) => ({ name, birthday });

const getAge = user => calculateAge(user.birthday);

const isAdult = user => getAge(user) >= 18;

// Esta función no forma parte de la interfaz de la abstracción User.
// Es una función "interna".
const calculateAge = (birthday) => {
  const milliSecondsInYear = 31556926 * 1000;

  // Date.now() devuelve la cantidad de milisegundos transcurridos desde el 1 de enero de 1970 00:00:00 UTC
  // Date.parse(str) analiza una representación de fecha en formato de cadena y también devuelve la cantidad de milisegundos
  return Math.trunc((Date.now() - Date.parse(birthday)) / milliSecondsInYear);
};

En abstracciones complejas (que pueden ser representadas por bibliotecas externas), la cantidad de funciones no interfaz es mucho mayor que las funciones interfaz. Incluso puede haber una o dos funciones que son la interfaz de la biblioteca, pero dentro de la biblioteca hay cientos de funciones. La calidad de su abstracción se determina, en parte, por la facilidad de uso de su interfaz.