Solucionado (ver solución)
Solucionado
(ver solución)
2
respuestas

Concepto de Interfaz

Hola a todos! Quisiera hablar sobre lo es una interfaz y saber si mas o menos el concepto es el acertado. Cualquier agregado sobre este concepto sería genial.

Por lo que entiendo una interfaz es como una clase abstracta que tiene métodos. Y que al llamar el método de la interfaz dependiendo del objeto invocado como parámetro devuelven resultados diferentes.

En el ejemplo de abajo con las clases Empleado, Cliente (ambas teniendo el método autenticable() que devuelven diferentes resultados) y la clase SistemaAutenticacion que tiene un método llamado login() que utiliza como parámetro un objeto y la idea es que tenga el método autenticable().

Entonces la interfaz lo que hará nomas es ejecutar un método que utiliza como parámetro a la instancia de un objeto. Y dentro de este método utiliza a la instancia del objeto para que acceda a su método.

Entonces el resultado del ejemplo de abajo será true porque al utilizar el método del empleado compara las claves y son iguales. Pero cuando se utiliza el del cliente, el autenticable solo devuelve el falso. Porque el login del cliente siempre dará falso y da igual si las claves son iguales o no.

Ingrese aquí la descripción de esta imagen para ayudar con la accesibilidad Ingrese aquí la descripción de esta imagen para ayudar con la accesibilidad Ingrese aquí la descripción de esta imagen para ayudar con la accesibilidad Ingrese aquí la descripción de esta imagen para ayudar con la accesibilidad

2 respuestas

"Entonces la interfaz lo que hará nomas es ejecutar un método " La interfaz no tiene métodos para ejecutar! Sus métodos no tiene cuerpo "{}". Ejemplo una interfaz es como un marco que te determina y obliga usar métodos a los objetos que de él derivan.

ejemplo: interfaz persona persona() calcular_datos_personales();

ahora si tengo que crear un objeto empleado y que extienda de persona - empleado se ve obligado a sobrescribir el método calcular_datos_personales();

Entonces todos aquellos objetos que extiendan de persona como cliente , también deben sobre escribir ese método. En la interfaz es como determinar que métodos deben tener todos aquellos objetos que extiendan de persona. Independientemente de los métodos que cada clase cree de forma particular. Espero que se entienda . saludos

solución!

La interfaz, como concepto general, establece un contrato de "qué comportamiento se debe tener" . Las clases que implementen una interfaz, deben cumplir con dicho contrato. Por otra parte, el contrato puede ser lógico o abstracto, en el sentido que el lenguaje no valida que la interfaz se cumpla, sino que es tarea del programador cumplir el contrato.

Es importante hacer esta distinción, debido a que javascript no está orientado en clases, sino en prototipos, así que el lenguaje no tiene recursos para representar y validar una "interfaz", en su lugar el programador debe encargarse, ya sea textualmente, a través de la documentación, o bien codificar dichas validaciones, sea cual sea la opción, el concepto de "interfaz" existe, mas no es un recurso del lenguaje.

The javascript way: En javascript puedes obligar a las clases a cumplir una interfaz, actualmente existen dos formas muy conocidas, y no son excluyentes, a veces te servirá más una, que otra.

1. Ducktyping

Debido a que javascript es un lenguaje débilmente tipado, en lugar de comprobar si una clase implementa una interfaz, simplemente inspeccionas las propiedades del objeto, para ver si cumple o no con la interfaz. En tu caso, Empleado, Cliente, implementan la interfaz Autenticable, que simplemente contiene un método, llamado autenticable. Lo normal es simplemente constar qué es un objeto Autenticable, y documentarlo dentro del código, en mi ejemplo se documentó el código con jsdocs, y se utilizo typedef, aunque esto es opcional, lo importante es que tú y tus compañeros sepan de qué trata un objeto Autenticable

/** 
 * @typedef {Object} Autenticable
 * @property {function} autenticable
 */
class SistemaAutentificacion {
    /**
     * Inicia sesión
     * @param {Autenticable} usuario a iniciar sesion
     * @param {string} clave del usuario
     */
    static login(usuario, clave) {
        if (isAutenticable(usuario)) {
            return usuario.autenticable(clave)
        }
        return false
    }
}

function isAutenticable(auten) {
    if (typeof(auten) === 'object' && typeof(auten.autenticable) === 'function') {
        return true
    }
    return false
}

Luego podrías hacer cosas como

const usuario = { name: 'Eduen',  autenticable: () => true }
SistemaAutentificacion.login(usuario, 'password') // true

Lo importante es notar que la interfaz pertenece al "objeto" y no a la clase, el método puede definirse como una propiedad propia del objeto, o bien pertenecer en el prototipado del mismo (heredado de una clase).

2. Prototipado

A diferencia del ducktyping, esta solución busca utilizar instanceof como sistema de tipos, por ende, se crea una clase que represente la interfaz, y todas las clases que implementen la interfaz, deberán extender de esta clase, y sobreescribir las funciones de la interfaz.

class Autenticable {
    autenticable(clave) {
        throw new Error('sin implementar')
    }
}

class Empleado extends Autenticable {
    /* Override */
    autenticable(clave) {
        return (clave == this.#clave)
    }
}

class Cliente extends Autenticable {
    /*Override*/
    autenticable(clave) {
        return false
    }
}

class SistemaAutentificacion {
    static login(usuario, clave) {
        if (usuario instanceof Autenticable) {
            return usuario.autenticable(clave)
        }
        return false
    }
}

Algunos ejemplos:

var obj1 = {autenticable: () => true}
var obj2 = new Autenticable()
var obj3 = new Empleado()
obj3.#clave = 'foo'
var obj4 = new Cliente()
SistemaAutentificacion.login(obj1, 'foo') // falso, obj1 no es instancia de Autenticable
SistemaAutentificacion.login(obj2, 'foo') // Error 'sin implementar', no puedes crear objetos utiles desde la interfaz
SistemaAutentificacion.login(obj3, 'foo') // true
SistemaAutentificacion.login(obj4, 'foo') // false

Espero haberte aclarado un par de dudas, saludos