Ho questo semplice caso d'uso / esempio basato su funzionalità per WeakMaps.
GESTISCI UNA COLLEZIONE DI UTENTI
Ho iniziato con un User
oggetto le cui proprietà comprendono una fullname
, username
, age
, gender
e un metodo chiamato print
che stampa un riassunto leggibile delle altre proprietà.
/**
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}`);
}
Ho quindi aggiunto una mappa chiamata users
per mantenere una raccolta di più utenti su cui sono codificati username
.
/**
Collection of Users, keyed by username.
*/
var users = new Map();
L'aggiunta della Collezione richiedeva anche funzioni di supporto per aggiungere, ottenere, eliminare un Utente e persino una funzione per stampare tutti gli utenti per completezza.
/**
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 tutto il codice sopra in esecuzione, diciamo NodeJS , solo la users
mappa ha il riferimento agli oggetti utente all'interno dell'intero processo. Non ci sono altri riferimenti ai singoli oggetti utente.
Eseguendo questo codice una shell NodeJS interattiva, proprio come un esempio, aggiungo quattro utenti e li stampa:
AGGIUNGI ALTRE INFORMAZIONI AGLI UTENTI SENZA MODIFICARE IL CODICE ESISTENTE
Ora supponiamo che sia necessaria una nuova funzionalità in cui i collegamenti di Social Media Platform (SMP) di ciascun utente devono essere tracciati insieme agli Oggetti utente.
La chiave qui è anche che questa funzione deve essere implementata con un intervento minimo al codice esistente.
Questo è possibile con WeakMaps nel modo seguente.
Aggiungo tre WeakMaps separate per 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();
Una funzione di supporto getSMPWeakMap
viene aggiunta semplicemente per restituire la WeakMap associata al nome SMP specificato.
/**
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 funzione per aggiungere un collegamento SMP degli utenti alla WeakMap SMP fornita.
/**
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 funzione per stampare solo gli utenti presenti sul dato SMP.
/**
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)}`)
}
});
}
È ora possibile aggiungere collegamenti SMP per gli utenti, anche con la possibilità che ciascun utente disponga di un collegamento su più SMP.
... continuando con l'esempio precedente, aggiungo i collegamenti SMP agli utenti, più collegamenti per gli utenti Bill e Sarah e quindi stampo i collegamenti per ciascun SMP separatamente:
Ora supponiamo che un utente venga eliminato dalla users
mappa chiamando deleteUser
. Ciò rimuove l'unico riferimento all'oggetto utente. Questo a sua volta cancellerà anche il collegamento SMP da qualsiasi / tutte le WeakMaps SMP (di Garbage Collection) poiché senza l'oggetto utente non è possibile accedere a nessuno dei suoi collegamenti SMP.
... continuando con l'esempio, elimino l'utente Bill e quindi stampo i collegamenti degli SMP a cui era associato:
Non è richiesto alcun codice aggiuntivo per eliminare singolarmente il collegamento SMP separatamente e il codice esistente prima che questa funzione non sia stata modificata in alcun modo.
Se esiste un altro modo per aggiungere questa funzione con / senza WeakMaps, non esitate a commentare.