Tengo este caso / ejemplo de uso basado en características simples para WeakMaps.
GESTIONAR UNA COLECCIÓN DE USUARIOS
Me comenzó con un User
objeto cuyas propiedades incluir una fullname
, username
, age
, gender
y un método llamado print
que imprime un resumen legible por humanos de las otras propiedades.
/**
Basic User Object with common properties.
*/
function User(username, fullname, age, gender) {
this.username = username;
this.fullname = fullname;
this.age = age;
this.gender = gender;
this.print = () => console.log(`${this.fullname} is a ${age} year old ${gender}`);
}
Luego agregué un Mapa llamado users
para mantener una colección de múltiples usuarios que están codificados por username
.
/**
Collection of Users, keyed by username.
*/
var users = new Map();
La adición de la Colección también requería funciones auxiliares para agregar, obtener, eliminar un Usuario e incluso una función para imprimir a todos los usuarios en aras de la integridad.
/**
Creates an User Object and adds it to the users Collection.
*/
var addUser = (username, fullname, age, gender) => {
let an_user = new User(username, fullname, age, gender);
users.set(username, an_user);
}
/**
Returns an User Object associated with the given username in the Collection.
*/
var getUser = (username) => {
return users.get(username);
}
/**
Deletes an User Object associated with the given username in the Collection.
*/
var deleteUser = (username) => {
users.delete(username);
}
/**
Prints summary of all the User Objects in the Collection.
*/
var printUsers = () => {
users.forEach((user) => {
user.print();
});
}
Con todo el código anterior ejecutándose, digamos NodeJS , solo el users
Mapa tiene la referencia a los Objetos de usuario en todo el proceso. No hay otra referencia a los Objetos de usuario individuales.
Ejecutando este código un shell interactivo de NodeJS, como ejemplo, agrego cuatro usuarios e los imprimo:
AGREGAR MÁS INFORMACIÓN A LOS USUARIOS SIN MODIFICAR EL CÓDIGO EXISTENTE
Ahora supongamos que se requiere una nueva función en la que los enlaces de la Plataforma de redes sociales (SMP) de cada usuario deben rastrearse junto con los Objetos de usuario.
La clave aquí también es que esta característica debe implementarse con una intervención mínima al código existente.
Esto es posible con WeakMaps de la siguiente manera.
Agrego tres WeakMaps separados para Twitter, Facebook, LinkedIn.
/*
WeakMaps for Social Media Platforms (SMPs).
Could be replaced by a single Map which can grow
dynamically based on different SMP names . . . anyway...
*/
var sm_platform_twitter = new WeakMap();
var sm_platform_facebook = new WeakMap();
var sm_platform_linkedin = new WeakMap();
Se getSMPWeakMap
agrega una función auxiliar simplemente para devolver el WeakMap asociado con el nombre SMP dado.
/**
Returns the WeakMap for the given SMP.
*/
var getSMPWeakMap = (sm_platform) => {
if(sm_platform == "Twitter") {
return sm_platform_twitter;
}
else if(sm_platform == "Facebook") {
return sm_platform_facebook;
}
else if(sm_platform == "LinkedIn") {
return sm_platform_linkedin;
}
return undefined;
}
Una función para agregar un enlace SMP de usuarios al WeakMap SMP dado.
/**
Adds a SMP link associated with a given User. The User must be already added to the Collection.
*/
var addUserSocialMediaLink = (username, sm_platform, sm_link) => {
let user = getUser(username);
let sm_platform_weakmap = getSMPWeakMap(sm_platform);
if(user && sm_platform_weakmap) {
sm_platform_weakmap.set(user, sm_link);
}
}
Una función para imprimir solo los usuarios que están presentes en el SMP dado.
/**
Prints the User's fullname and corresponding SMP link of only those Users which are on the given SMP.
*/
var printSMPUsers = (sm_platform) => {
let sm_platform_weakmap = getSMPWeakMap(sm_platform);
console.log(`Users of ${sm_platform}:`)
users.forEach((user)=>{
if(sm_platform_weakmap.has(user)) {
console.log(`\t${user.fullname} : ${sm_platform_weakmap.get(user)}`)
}
});
}
Ahora puede agregar enlaces SMP para los usuarios, también con la posibilidad de que cada usuario tenga un enlace en múltiples SMP.
... continuando con el ejemplo anterior, agrego enlaces SMP a los usuarios, enlaces múltiples para los usuarios Bill y Sarah y luego imprimo los enlaces para cada SMP por separado:
Ahora digamos que un usuario se elimina del users
mapa llamando deleteUser
. Eso elimina la única referencia al objeto de usuario. Esto a su vez también borrará el enlace SMP de cualquiera / todos los WeakMaps SMP (por Garbage Collection) ya que sin el objeto de usuario no hay forma de acceder a ninguno de sus enlaces SMP.
... continuando con el Ejemplo, elimino al usuario Bill y luego imprimo los enlaces de los SMP con los que estaba asociado:
No se requiere ningún código adicional para eliminar individualmente el enlace SMP por separado y el código existente antes de esta función no se modificó de ninguna manera.
Si hay alguna otra forma de agregar esta función con / sin WeakMaps, no dude en comentar.