Mam tę prostą przypadek użycia / Przykład dla WeakMaps.
ZARZĄDZAJ KOLEKCJĄ UŻYTKOWNIKÓW
Zacząłem z User
obiektu, którego właściwości należą fullname
, username
, age
, gender
oraz metodę zwaną print
która drukuje czytelny dla człowieka podsumowanie innych właściwości.
/**
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}`);
}
Następnie dodałem Mapę, users
aby zachować zbiór wielu użytkowników, których kluczem jest username
.
/**
Collection of Users, keyed by username.
*/
var users = new Map();
Dodanie kolekcji wymagało również funkcji pomocniczych do dodawania, pobierania, usuwania użytkownika, a nawet funkcji drukowania wszystkich użytkowników w celu zapewnienia kompletności.
/**
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();
});
}
Przy włączonym całym powyższym kodzie, powiedzmy NodeJS , tylko users
mapa ma odniesienie do obiektów użytkownika w całym procesie. Nie ma innych odniesień do poszczególnych obiektów użytkownika.
Uruchamiając ten kod interaktywną powłokę NodeJS, tak jak w przykładzie dodaję czterech użytkowników i drukuję ich:
DODAJ WIĘCEJ INFORMACJI DLA UŻYTKOWNIKÓW BEZ MODYFIKOWANIA ISTNIEJĄCEGO KODU
Powiedzmy teraz, że wymagana jest nowa funkcja, w której łącza użytkowników SMP (Social Media Platform) muszą być śledzone wraz z obiektami użytkownika.
Kluczem tutaj jest również to, że ta funkcja musi zostać zaimplementowana przy minimalnej interwencji w istniejący kod.
Jest to możliwe dzięki WeakMaps w następujący sposób.
Dodaję trzy osobne WeakMapy dla Twittera, Facebooka, 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();
Dodano funkcję pomocnika, getSMPWeakMap
aby zwrócić WeakMap powiązaną z podaną nazwą SMP.
/**
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;
}
Funkcja dodawania linku SMP użytkownika do danej SMP WeakMap.
/**
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);
}
}
Funkcja drukowania tylko użytkowników obecnych na danym 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)}`)
}
});
}
Możesz teraz dodawać łącza SMP dla użytkowników, również z możliwością, że każdy użytkownik będzie miał łącze na wielu SMP.
... kontynuując wcześniejszy przykład, dodałem łącza SMP do użytkowników, wiele łączy dla użytkowników Bill i Sarah, a następnie wydrukowałem łącza dla każdego SMP osobno:
Teraz powiedz, że użytkownik został usunięty z users
mapy, dzwoniąc deleteUser
. To usuwa jedyne odniesienie do obiektu użytkownika. To z kolei usunie również łącze SMP z dowolnego / wszystkich SMP WeakMaps (Garbage Collection), ponieważ bez obiektu użytkownika nie ma możliwości uzyskania dostępu do żadnego z jego łączy SMP.
... kontynuując Przykład, usuwam użytkownika Billa, a następnie drukuję linki o SMP, z którymi był powiązany:
Nie ma wymogu żadnego dodatkowego kodu, aby osobno usunąć łącze SMP osobno, a istniejący kod, zanim ta funkcja i tak nie zostanie zmodyfikowana.
Jeśli istnieje inny sposób dodania tej funkcji z / bez WeakMaps, prosimy o komentarz.