Eu tenho esse caso de uso baseado em recursos simples / exemplo para WeakMaps.
GERIR UMA COLEÇÃO DE USUÁRIOS
Comecei com um User
objeto cujas propriedades incluem um fullname
, username
, age
, gender
e um método chamado print
que imprime um resumo legível das outras propriedades.
/**
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}`);
}
Em seguida, adicionei um mapa chamado users
para manter uma coleção de vários usuários digitados por username
.
/**
Collection of Users, keyed by username.
*/
var users = new Map();
A adição da coleção também exigia funções auxiliares para adicionar, obter, excluir um usuário e até uma função para imprimir todos os usuários por uma questão de integridade.
/**
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();
});
}
Com todo o código acima em execução, digamos NodeJS , apenas o users
Mapa tem a referência aos Objetos do Usuário em todo o processo. Não há outra referência aos objetos de usuário individuais.
Executando este código um shell NodeJS interativo, apenas como um exemplo, adiciono quatro usuários e os imprimo:
ADICIONE MAIS INFORMAÇÃO AOS USUÁRIOS SEM MODIFICAR O CÓDIGO EXISTENTE
Agora, digamos que um novo recurso seja necessário, em que os links de SMP (Social Media Platform) de cada usuário precisam ser rastreados junto com os Objetos de Usuário.
A chave aqui é também que esse recurso deve ser implementado com o mínimo de intervenção no código existente.
Isso é possível com o WeakMaps da seguinte maneira.
Eu adiciono três 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();
Uma função auxiliar getSMPWeakMap
é adicionada simplesmente para retornar o WeakMap associado ao nome SMP fornecido.
/**
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;
}
Uma função para adicionar o link SMP de um usuário ao SMP WeakMap fornecido.
/**
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);
}
}
Uma função para imprimir apenas os usuários presentes no SMP especificado.
/**
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)}`)
}
});
}
Agora você pode adicionar links SMP para os usuários, também com a possibilidade de cada usuário ter um link em vários SMPs.
... continuando com o exemplo anterior, adiciono links SMP aos usuários, vários links para os usuários Bill e Sarah e imprimo os links para cada SMP separadamente:
Agora diga que um usuário é excluído do users
mapa chamando deleteUser
. Isso remove a única referência ao objeto de usuário. Isso, por sua vez, também limpará o link SMP de qualquer / todos os SMP WeakMaps (por Garbage Collection), pois sem o Objeto do Usuário, não há como acessar qualquer link SMP.
... continuando com o exemplo, excluo o usuário Bill e imprimo os links dos SMPs aos quais ele foi associado:
Não há necessidade de qualquer código adicional para excluir individualmente o link SMP separadamente e o código existente antes que esse recurso não fosse modificado.
Se houver outra maneira de adicionar esse recurso com / sem WeakMaps, fique à vontade para comentar.