Skip to content

Instantly share code, notes, and snippets.

@phillippelevidad
Created November 6, 2023 21:08
Show Gist options
  • Save phillippelevidad/a2afeb85d6773f07a7659774e0534c6d to your computer and use it in GitHub Desktop.
Save phillippelevidad/a2afeb85d6773f07a7659774e0534c6d to your computer and use it in GitHub Desktop.
Implementação de Decorator em Javascript
// Como visto em
// https://refactoring.guru/design-patterns/decorator
// https://www.youtube.com/watch?v=GCraGHx6gso
// Artifício para simular uma interface
// e obrigar a implementação dos métodos
class IRepository {
find(filter) {
throw new Error("Method 'find' must be implemented");
}
}
// Classe repositório, que será decorada
class MyRepository extends IRepository {
find(filter) {
return db.collection.find(filter);
}
}
// Decorator que adiciona uma camada de cache
// Os decorators devem ter o mesmo tipo de base ou interface
// que os objetos que eles decoram
class CachingDecorator extends IRepository {
constructor(decoratedRepository) {
this.decoratedRepository = decoratedRepository;
}
find(filter) {
const cacheKey = createKey(filter);
if (!cache[cacheKey]) {
const result = this.decoratedRepository.find(filter);
cache[cacheKey] = result;
}
return cache[cacheKey];
}
}
// Decorator que adiciona uma camada de log
class DbLoggingDecorator extends IRepository {
constructor(decoratedRepository) {
this.decoratedRepository = decoratedRepository;
}
find(filter) {
console.log("Database called", filter);
return this.decoratedRepository.find(filter);
}
}
// Uso dos decorators
const repo = new MyRepository();
const logging = new DbLoggingDecorator(repo);
const cachingAndLogging = new CachingDecorator(logging);
// A primeira chamada vai bater no banco de dados e fazer log
const result1 = cachingAndLogging.find({ id: 999 });
// A segunda chamada vai bater no cache e retornar direto
const result2 = cachingAndLogging.find({ id: 999 });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment